facebook twitter hatena line google mixi email
★お気に入り追加


■ このスレッドは過去ログ倉庫に格納されています

おそらく、.NET開発でデファクトスタンダードに最も近いであろう
C++/CLIについて語ろうぜ!

このスレはC++および.NET Frameworkについて一定以上の知識を持っている人が対象となります。
.NETのクラスライブラリの使い方といった質問は Visual Studioスレにお願いします。

前スレッドはこちら
くだすれC++/CLI(初心者用)
http://pc8.2ch.net/test/read.cgi/tech/1142144110/l1

dat落ち姉妹スレ
C++/CLI part3
http://pc12.2ch.net/test/read.cgi/tech/1206447234/l1
http://pc11.2ch.net/test/read.cgi/tech/1142147319/l1
http://pc8.2ch.net/test/read.cgi/tech/1126450441/l1

managed C++ やろうぜ!! 002
http://pc8.2ch.net/test/read.cgi/tech/1139043535/l1

ここまで見た
  • 871
  •  
  • 2014/10/22(水) 13:38:11.49
C#みたいにCodeProviderで動的な文字列をコンパイルして
実行したいんですが、もしかしたらC++/CLIにはCodeProviderが
ないですか?

ここまで見た
  • 872
  •  
  • 2014/10/22(水) 13:43:12.37
すいません、抜けてました。
CodeDomProviderを継承したCodeProviderです

ここまで見た
  • 873
  •  
  • 2014/10/22(水) 17:09:24.88
まあ混合型使えないからそれならC#でいいじゃんってことになるよね

ここまで見た
  • 874
  •  
  • 2014/11/11(火) 14:49:35.49
C++のDLLをC#で使いたいのですがC++/CLIで吸収したほうがいいのかな?
C++の構造体のポインタとかあってわけわからん

ここまで見た
  • 875
  •  
  • 2014/11/11(火) 16:50:02.76
構造体 マーシャリング でぐぐる

ここまで見た
  • 876
  •  
  • 2014/11/12(水) 00:51:06.13
>>874の件ですがC#でなんとかがんばることにしました
お騒がせしました

ここまで見た
  • 877
  •  
  • 2014/12/09(火) 00:10:16.60
C++/cli からC++のプロジェクトに定義している関数を呼び出したいんです。
C++プロジェクトのlibファイルを参照し、includeファイルをC++/cli側に
持ってきて#include すると、物凄い数のエラーがでます。

(C2011:C2079:C2504:C3395:C3699)

[1] C++/cliで参照できるよう、ビルドエラーを直すしかない

[2] 別の方法でC++の関数をビルドエラー無しに参照できる。

ちなみに、C++の関数を参照しないで自作・・・という回答は無しでお願いします。

ここまで見た
  • 878
  •  
  • 2014/12/09(火) 10:30:47.48
物凄い数のエラーじゃなくてエラーの内容をチェックしろよ。
出力ログのエラーの行をダブルクリックすると問題の箇所に飛ぶから
何で再定義だとか定義がないと言われてるか考えろ。
何でその程度のレベルでC++/CLIとかやってんの。

ここまで見た
  • 879
  •  
  • 2014/12/09(火) 10:30:56.11
1.C++から呼び出す
2.C#に移植する

C++/CLIでなきゃいけない理由なんてあるん?

ここまで見た
  • 880
  • 878
  • 2014/12/09(火) 22:59:58.60
すみません、初心者なりにエラーの原因を調べてきました。

a.h

class A : public B {}

b.h

class B {}



この時に Class B で再定義のエラーが発生していました。

a.h が先にincludeされているのが問題で、b.h を先にinclude するよう
ソース修正すれば良い・・・・・ということでしょうか??

ここまで見た
  • 881
  •  
  • 2014/12/11(木) 12:05:51.55
各ヘッダの先頭に#pragma onceと書く

a.hでb.hのクラスを使っているなら
a.h内でb.hをinludeしろ

cpp側でincludeの順を気にしなきゃならないのは糞

ここまで見た
  • 882
  •  
  • 2014/12/15(月) 20:00:30.77
質問です。

任意の型のマネージド配列(cli::array)を、任意の個数、引数として受け取って
それらの配列としての長さの最小値を返す関数を書きたいと思っています。

イメージとしては、
array<String^> arrStr = gcnew array<String^>(6);
array<double> arrDob = gcnew array<double>(8);
array<int> arrInt = gcnew array<int>(3);
に対して、
Function(arrStr, arrDob) = 6
Function(arrStr, arrDob, arrInt) = 3
となるような関数Functionを書きたいと思っています。

しかし、この場合の引数リストの書き方がよくわかりません。
単純に可変長の引数リストだとFunction(... array<Object^>^ args)みたいな
書き方になると思うんですが、これをマネージド配列の配列だからといって
真似てFunction(... array<array<Object^>^>^ arrays)みたいな書き方をしても、
呼び出し側(例えばFunction(arrStr, arrDob)とか)で引数リストが一致しない旨
怒られます。このような場合の適切な引数リストの書き方ってありますか?

あるいは回避策として、引数はFunction(... array<Object^>^ args)としておき
この関数の中でfor each (Object^ arg in args) { argが配列かどうか }という
コードもありえますが、肝心の、「argが配列かどうか」チェックするコードが
わかりません。

上記いずれか一方で構いませんので、解決策をご教授いただけないでしょうか?

ここまで見た
  • 883
  •  
  • 2014/12/15(月) 20:51:05.44
... System::Array^ args
arg->GetLength

... System::Collections::IList^ args
arg->Count

ここまで見た
  • 884
  •  
  • 2014/12/15(月) 22:28:59.04
>>883
試してみましたが、いずれの場合もコンパイルエラーC3132が発生します。

そもそもargの型を何に指定すべきなのか、というのがよくわかっていません。
例えば
int Function(... array<Object^>^ args)
{
  int MinLength = -1;
  for each(array<Object^>^ arg in args)
  {
    if ( (MinLength < 0) || (arg->Length < MinLength) )
    {
      MinLength = arg->Length;
    }
  }
  return MinLength;
}
みたいなコードだと、Function(arrStr, arrInt)を実行したとき、それら引数を
System.Object[]にキャストできない旨を怒られます。

ここまで見た
  • 885
  •  
  • 2014/12/15(月) 22:43:22.71
ごめんちょっとぼけてた
... array<System::Array^>^ args
for each (auto arg in args) { int len = arg->GetLength(0);
... array<System::Collections::IList^>^ args
for each (auto arg in args) { int len = arg->Count;

ここまで見た
  • 886
  •  
  • 2014/12/15(月) 22:49:54.98
>>885
うまくいきました!
動作版のコードは以下の通りです。

int Function(... array<System::Array^>^ args)
{
  int MinLength = -1;
  for each(auto arg in args)
  {
    if ( (MinLength < 0) || (arg->Length < MinLength) )
    {
      MinLength = arg->Length;
    }
  }
  return MinLength;
}

ありがとうございました。

ここまで見た
  • 887
  •  
  • 2015/01/28(水) 22:20:24.42
String^ selectedEmployee = (String^)(ComboBox1->SelectedItem);

^ってどういう意味?

ここまで見た
  • 888
  •  
  • 2015/01/28(水) 22:43:41.32
トラッキングハンドルって意味

ここまで見た
  • 889
  •  
  • 2015/01/30(金) 16:37:12.12
こらこら。
普通のC++でいうところの*だよ。

ここまで見た
  • 890
  •  
  • 2015/02/06(金) 15:15:17.14
>>887
参照型

ここまで見た
  • 891
  •  
  • 2015/03/01(日) 13:44:47.71
既存の native C++ のプログラムからC#で作ったdllを呼び出す必要が出てきたんで
/clrを使おうと思うんだが、.NETを使う部分以外のソースを全部 #pragma unmanaged
しておけば既存のnativeのプログラムと変わらないと考えていいのかな?
スタートアップに時間がかかったりするかもしれないけど。
それ以外になにか、純粋なnativeアプリと比べてのデメリットとかあるだろうか?

ここまで見た
  • 892
  •  
  • 2015/03/03(火) 10:49:44.41
拡張する度にpragma追加するのが面倒くさいからCOM exportのがいいよ

ここまで見た
  • 893
  •  
  • 2015/03/03(火) 22:20:54.28
COMはregistryやGACに登録しないとならないのが。それがなければ使いたいんだけど。
pragamはまぁ、stdafx.hに仕込んどけばいいだけなんで。
で、試してみて一応ビルドは通って、DependencyWalkerで見てもほとんど同じに見えたけど、
起動時に例外が出てうまく立ち上がらなかった。
どちらにしても、ビルドに時間がかかるんで普通にwrapperだけC++/CLIで作った方が楽そう。

ここまで見た
  • 894
  •  
  • 2015/03/03(火) 23:37:18.31
Register freeのcomが良い

ここまで見た
  • 895
  •  
  • 2015/03/04(水) 00:00:58.99
ほー、Interopでも登録なしで使えたのか。知らんかった。

ここまで見た
  • 896
  •  
  • 2015/04/11(土) 23:36:34.69
http://peace.2ch.net/test/read.cgi/tech/1420379468/279
から誘導されてきました。

質問です。

実行時にフォームをイベントごとコピーしたいのですが、
元のイベント関数のハンドラが取れず、上手く行きません。
解決策があれば教えてください。

やりたいこと:
チェックボックス等のフォームをデザイナで指定し、イベント関数もデザイナで指定します。
プログラムでこのチェックボックス等を10個ほどにコピーし、並べます。
このときにプロパティ等はコピーできますが、イベント関数がコピーできません。

理由:
位置決めが楽なので、デザイナ側で頭のFormは指定したいのです。
そして管理上分かりやすいので、イベントもそこに書いて、これをコピーしようとしています。
ところがEventInfo::GetRaiseMethodではnullが返ってきてしまいます。
ハンドラさえ取れれば以下と組み合わせて上手く行くと思うのですが。
https://msdn.microsoft.com/ja-jp/library/ms228976%28v=vs.110%29.aspx

状況:
なおC#だと以下で上手く行きます。
http://stackoverflow.com/questions/6055038/how-to-clone-control-event-handlers-at-run-time
ただしC++だと、GetField("events")がnullptrを返してくるので駄目です。
キーワードは色々試してみましたが、当たりませんでした。

前から困っている点で、とらいえずいちいち書いて対応していますが、
見ていて汚いので書き直したいと思っています。
気長に待っていますので、どなたか対策をご存じの方はレスよろしくお願いします。

ここまで見た
  • 897
  •  
  • 2015/04/12(日) 03:07:38.87
auto f = (Component::typeid)->GetField("events", BindingFlags::NonPublic | BindingFlags::Instance);
auto v = f->GetValue(checkBox1);
f->SetValue(checkBox2, v);

でふるまいが同一になるけど。

ここまで見た
  • 898
  •  
  • 2015/04/12(日) 03:39:58.42
>>897
お早い回答ありがとうございます。
こちらで確認した結果、確かに動きました。

(Component::typeid) のところを私は Component::GetType() にしていたのが敗因のようです。
見よう見まねでやっているため、実はここら辺のところがいまいち分かっていません。
お手数をおかけ致しました。また、ありがとうございました。

ここまで見た
  • 899
  •  
  • 2015/04/12(日) 03:49:39.70
Component::GetType() は Form の中でなら GetType() と同じ。
C++で親クラスのメソッド呼ぶときの文法よ。

ここまで見た
  • 900
  •  
  • 2015/04/12(日) 10:00:53.76
>>899
了解です。ありがとうございます。
FormがComponentを継承しているのを関知していませんでした。

ここまで見た
  • 901
  • 897
  • 2015/04/15(水) 19:57:16.10
>>897
これ、少なくとも numericUpDown の ValueChanged イベントはコピーできないことが分かりました。
その他は不明です。
元々このやり方はどのドキュメントにも書いていないらしいので、文句は言えないのですが、
どなたか解決策をご存じであれば教えてください。

なお、Button の Click イベントについては、また別の解を見つけました。
似たようなものですが、keyが必要なようです。
http://stackoverflow.com/questions/293007/is-it-possible-to-steal-an-event-handler-from-one-control-and-give-it-to-anoth
ただ、Button Click 自体はこちらで試す限り、 >>897 でコピーできています。

ここまで見た
  • 902
  •  
  • 2015/04/29(水) 20:01:07.13
マネージクラスのポインタを取得(pin_ptr)し、ネイティブクラスのポインタにキャストする方法を探しています。

class NativeClass
{
 int Hoge;
};

[StructLayout(LayoutKind::Sequential)]
public ref class ManagedClass
{
private:
 int mHoge;

public:
 property Int32 Hoge { Int32 get() { return this->mHoge; } }
};

mHogeがinternalの場合は下記でできますが、privateの場合はどう書けば良いのでしょうか?

ManagedClass^ managedClass = gcnew ManagedClass();
pin_ptr<int> pManagedClass = &managedClass->mHoge;
NativeClass* pNativeClass = (NativeClass*)pManagedClass;

ここまで見た
  • 903
  •  
  • 2015/04/29(水) 23:24:10.23
property const Int32% Hoge { const Int32% get() { return this->mHoge; } }
にすれば、&managedClass->Hoge が interior_ptr<const int> になるから後は適当にキャストすればいいんでは。

ここまで見た
  • 904
  •  
  • 2015/04/30(木) 23:38:42.52
>>903
返信ありがとうございます。
トラッキング参照のプロパティはC#側で扱えなくなってしまうので避けたいです。
フィールドを参照しないと無理みたいなので、mHogeを公開するようにしようと思います。
ありがとうございました。

ここまで見た
  • 905
  •  
  • 2015/05/01(金) 20:25:15.13
知ってるかもだけど、ManagedClass が value class, value struct なら
pin_ptr<ManagedClass> を reinterpret_cast<NativeClass *> するのは安全だったはず…

ここまで見た
  • 906
  •  
  • 2015/05/08(金) 23:36:54.66
MessageBoxを親の中央に表示する簡単な方法はないですか?
自分でフォームを作ってしまえばいいんでしょうか?
最近までVC++6.0でMFCしか触ったことない自宅へぼプログラマです

ここまで見た
  • 907
  •  
  • 2015/05/09(土) 21:01:16.72
フックでメッセージボックスのハンドルを取得して移動するだけ

ここまで見た
  • 908
  •  
  • 2015/05/19(火) 18:58:05.23
.NET Framework 4 で C++/CLI 混在モード アセンブリを使用すると、スレッドの生成・終了時にメモリ リークが生じる問題について
http://blogs.msdn.com/b/jpvsblog/archive/2015/05/18/mixedassembly-thread-leak.aspx

ここまで見た
  • 909
  •  
  • 2015/05/20(水) 10:30:15.88
うちのPCだと4.5.2が入らないんだけども
http://mog.tank.jp/up/src/mog11197.jpg

ここまで見た
  • 910
  •  
  • 2015/05/20(水) 22:52:40.74
>>909
そうそう、起動時なんか構成に失敗しましたとかでて毎回復帰がかかっている

ここまで見た
  • 911
  •  
  • 2015/05/20(水) 23:36:56.86
休日プログラマです。

環境:Visual Studio 2012 express
SQLサーバ:SQL Server 2012 express

ODBCドライバを用いて、フォームから検索ワードを取得し、
C++/CLIでのプリペアドステートメントを発行して結果を取得したいのですが、
それを用いたlikeなど部分検索SQLの結果取得でハマったまま先に進めません。

SQLCHAR search[255];
std string sql = "select hoge, strhoge from hogetbl where strhoge like \%?\%";
SQLPrepare(hstmt,
(SQLTCHAR *) sql.c_str(),
,SQL_NTS);
SQLBindParameter(hstmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,sizeof(search),0,search,NULL);
SQLExecute(...

のように書いているのですが、プログラム上では何をやってもSQL_NO_DATAが返ります
あたりまえですがSQLそのものはServerのクエリで確認したところ通っています //?の所を'(任意文字列)'にした結果

また、SQL構文をLIKEの代わりにSQLのCHARINDEXを用い項目を増やして使ってみたのですが、同じようにダメでした。
// case when charindex(?,strhoge) > 0 then 1 else 0 end as searchflg ....
// where searchflg = 1 のように

ここには書き戻しできないのですが、escape句も試用したことがありますが、無理でした。
で、このLIKE以外は問題なく動きます。
また、他の機能はほとんどODBCで書いちゃったのでADOはやりたくないです。
何かいい方法ありませんでしょうか。よろしくお願いします。

ここまで見た
  • 912
  •  
  • 2015/05/20(水) 23:56:15.34
普通 '%' + ? + '%' とか書くんじゃないの。

ここまで見た
  • 913
  • 912
  • 2015/05/21(木) 00:02:48.74
ああ、言い忘れていてすみません。
それもやりましたが、ダメでした

ここまで見た
  • 914
  •  
  • 2015/05/21(木) 00:43:36.74
コマンドには like ? と書いて、パラメータに%を指定するのはどう?

ここまで見た
  • 915
  • 912
  • 2015/05/22(金) 01:16:43.85
うーん、それもやってみます。
あと、他の方はこうした事でハマったりは特にありませんでしたでしょうか。
書いてるのが一人でやってるのもあって、本当にプリペアドでの部分検索が可能かどうかが少し不安です
もちろん、突き詰めればなんでも可能なのでしょうけれども……

ここまで見た
  • 916
  •  
  • 2015/05/22(金) 02:49:24.89
SQLTCHAR* 型に std::string のポインタ渡してるのは、問題ないの?

ここまで見た
  • 917
  • 912
  • 2015/05/29(金) 21:54:54.52
912です。>>916さんの意見も含め、別の観点からもみてみたところ
・・・非常にお恥ずかしいオチになったのですが、解決しました。

問題はコードではなく、BindParameter時のCHAR検索する箇所(SQL_CHAR)が
DB側でいつの間にかvarcharになっていたのが原因でした。合わせてやると簡単に使えるように…
みなさん、お騒がせして申し訳ありません。

ここまで見た
  • 918
  • 912
  • 2015/05/29(金) 22:03:04.73
>>917
×CHAR検索する箇所(SQL_CHAR)がDB側でいつの間にかvarcharになっていた
○CHAR検索(SQL_CHAR)としていたのに、対象のDB側の項目の型がvarcharになっていた

ここまで見た
  • 919
  •  
  • 2015/09/15(火) 21:43:10.94
質問です。

上手いことsscanfを.NETで実装する方法ってありますか?
ポインタが上手く渡せず困っています。

なお、正式に習ったわけではなく、見よう見まねでやっているため、
単純なところで勘違いがあるかもしれませんが、その時も指摘して頂けたら助かります。

ここまで見た
  • 920
  •  
  • 2015/09/15(火) 21:43:39.42
【これまでの経緯】
プログラムが間延びしてきたため、
これまで個別にちまちま書いていたファイル読み出し部分をsscanfで纏めて整理しようとしています。
ググッたところ、.NETにはsscanfそのものはなく、どうやら皆さん苦労しているようでした。
http://stackoverflow.com/questions/4223917/c-sharp-equivalent-of-c-sscanf
http://stackoverflow.com/questions/492262/is-there-an-equivalent-to-sscanf-in-net
http://www.blackbeltcoder.com/Articles/strings/a-sscanf-replacement-for-net
ただ自分の場合はcsvの読み出しで順番と対象だけ指定できればいいので、
以下のように組んでみました。(ただしまだ動かしていないので動かないかもしれません)

private: int sscanf_csv(String^ str, String^ format, array<void**>^ pointers){
array<String^>^ strs = str->Split(',');
array<String^>^ fmts = format->Split(',');
int i=0;
while (i<strs->Length && i<fmts->Length) {
if (fmts[i]=="int") {
if (!Int32::TryParse(strs[i],(int%)pointers[i])) break;
} else if (fmts[i]=="double") {
if (!Double::TryParse(strs[i],(double%)pointers[i])) break;
} else if (fmts[i]=="float") {
if (!Single::TryParse(strs[i],(float%)pointers[i])) break;
} else if (fmts[i]=="string") {
*(interior_ptr<String^>)pointers[i] = strs[i];
}
i++;
}
return i;
}

Stringのところは怪しいですが、intとdoubleとfloatはネイティブなら問題ないと思っています。

ここまで見た
  • 921
  •  
  • 2015/09/15(火) 21:44:06.10
【問題点】
・マネージドのクラスではメンバにネイティブ配列が使えないため、
書き込み対象にどうしてもマネージド配列の要素を指定することが必要となりますが、
interior_ptrをvoid**にキャストできません。
仕様上、interior_ptr → pin_ptr → int → void** にはキャストできる(っぽい)のですが、
 ・interior_ptrは配列に出来ない(array<interior_ptr<int>> も interior_ptr<int> hoge[] もエラー)
 ・pin_ptrも同様に配列に出来ない。さらにローカル変数として宣言しないと駄目っぽい。
ため、これらを回避するためにはベタにコードする必要があり、余計に見にくくなります。
・そもそも void** にしているのは可変長引数がいまいちだったからなのですが、
上記のように interior_ptr が配列に取れないから多分可変長も無理です。
・自分の場合は1行につきせいぜい10個程度の代入なので最悪べた書きでラップしてもいいのですが、
interior_ptr<Type>は型指定があり、型の順番は変更したいのでこれも厳しいです。

【出来ればいいなと思っている記述】
array<int> ary_int = gcnew array<int>(10);
array<double> ary_double = gcnew array<double>(10);
sscanf_csv(line0, "int,double", gcnew array<void**>(2){&ary_int[0], &ary_double[0]});
sscanf_csv(line1, "double,int", gcnew array<void**>(2){&ary_double[1], &ary_int[1]});

という感じです。良い案があればお願い致します。

ここまで見た
  • 922
  •  
  • 2015/09/16(水) 11:35:11.25
>921
ttps://gist.github.com/anonymous/db1149cb0a1afbd1f6d8

書いてて思ったけど、変に凝るよりも↓みたいな奴の方が読む人にやさしい…
auto x = gcnew CSV(line1);
ary_int[0] = x->read_int(0);
ary_double[0] = x->read_double(1);

お絵かきランド
フリックラーニング
ここまで見た

★お気に入り追加

このページを共有する
facebook twitter hatena line google mixi email
おすすめワード