maaash.jp

what I create

C#とアンマネージドC++のDLL間で文字列の配列をやり取りする

マネージド環境(C#)からアンマネージド環境になんか渡す時にマーシャリングというのが自動で起きて、
変数の相互型変換をしてくれるようだ。
名前がわかりにくすぎる。

C#からC++に文字列の配列を渡すとこ

C#でC++dllの関数使うよって宣言
[csharp][DllImport(“pcp.dll”)]
private static extern int call_array([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 1)]string[] files, int length);
[/csharp]

C#側コード
[csharp]string[] files = new string[2];
files[0] = “日本語1″;
files[1] = “日本語2″;
int ret = call_array(files,2);
return ret;[/csharp]

C++側
[cpp]int call_array( wchar_t* files, int length ) {
setlocale(LC_ALL,”japanese”);
for ( int i=0; i<length; i++ ) {
wprintf(L”%d: %s\n”,i,
(files+i));
}
return 10;
}[/cpp]
defファイルに書いとく。

C++からC#のコールバックに文字列の配列を渡す

C#のコールバック
[csharp]public static int onReceivedFiles(IntPtr ptr, int nVal) {
IntPtr pptr;
string[] files = new string[nVal];
for( int n = 0; n < nVal; n++ ) {
// スタックに積まれて来るのはポインタのみなので
pptr = Marshal.ReadIntPtr( ptr, n * 4 );
files[n] = Marshal.PtrToStringAuto( pptr );
}
return 1;
}[/csharp]

コールバック関数を渡す先のC++側関数とdelegate
[cpp][DllImport(“pcp.dll”)]
private static extern int start(StringArrayCallback cb);
public delegate int StringArrayCallback(IntPtr ptr, int nVal);
[/cpp]

C++にコールバック関数を渡す
[cpp]StringArrayCallback cb = new StringArrayCallback(onReceivedFiles);
int ret = start(cb);[/cpp]

C++からC#のコールバック関数を呼ぶ
[cpp]std::wstring message1 = L”日本語1″;
std::wstring message2
= L”日本語2″;
wchar_t* messages_[2] = { (wchar_t*)message1_.c_str(), (wchar_t*)message2_.c_str() };
int ret = callback(messages_, sizeof(messages_)/sizeof(messages[0]));
[/cpp]

Comments