C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

C#から「ポインタを引数に持つDLL関数」の呼び方 /taro (20/10/13(Tue) 11:46) #95956
Re[1]: C#から「ポインタを引数に持つDLL関数」の呼び方 /Hongliang (20/10/13(Tue) 12:22) #95957
  └ Re[2]: C#から「ポインタを引数に持つDLL関数」の呼び方 /774RR (20/10/13(Tue) 13:16) #95958
    └ Re[3]: C#から「ポインタを引数に持つDLL関数」の呼び方 /taro (20/10/13(Tue) 14:13) #95959 解決済み


親記事 / ▼[ 95957 ]
■95956 / 親階層)  C#から「ポインタを引数に持つDLL関数」の呼び方
□投稿者/ taro (6回)-(2020/10/13(Tue) 11:46:28)

分類:[C#] 

VisualStudio2019で、C#の学習をしております。
当方、C++やJAVA等の他言語は多少の経験がありますが、C#は未経験です。


■やりたいこと
Cで書かれたDLL内に実装している、以下のような関数を、C#から呼び出したい。

[comm.h]
extern "C" COMM_API void PointerTest(char* buf);

[comm.cpp]
// 渡されたバッファに5byte分のデータをセットする
void PointerTest(char* buf)
{
  buf[0] = 0x00;
  buf[1] = 0x10;
  buf[2] = 0x20;
  buf[3] = 0x30;
  buf[4] = 0x40;
}


■困っていること
C#側で、どのように呼び出せばよいのか分かりません。
DLL側でセットする内容が文字列なら、string型変数を引数に渡せばよいのでしょうが、文字列ではないので「IntPtr」型変数を渡す?

[test.cs]
byte[] data = new byte[10];  // 最終的に、このバッファに値をセットしたい
IntPtr buffer = new IntPtr();
buffer = Marshal.AllocHGlobal(10);
PointerTest(buf);
data = Marshal.ReadIntPtr(buffer);  // ←コンパイルエラーなので、この行が間違っている?
Marshal.FreeHGlobal(buffer);



よろしくお願いします。

[ □ Tree ] 返信 編集キー/

▲[ 95956 ] / ▼[ 95958 ]
■95957 / 1階層)  Re[1]: C#から「ポインタを引数に持つDLL関数」の呼び方
□投稿者/ Hongliang (1095回)-(2020/10/13(Tue) 12:22:14)
[DllImport(略)]
static extern void PointerTest([Out] byte[] buf);
で十分です。
[ 親 95956 / □ Tree ] 返信 編集キー/

▲[ 95957 ] / ▼[ 95959 ]
■95958 / 2階層)  Re[2]: C#から「ポインタを引数に持つDLL関数」の呼び方
□投稿者/ 774RR (833回)-(2020/10/13(Tue) 13:16:45)
これだけで Marshal 系も不要

byte[] b = new byte[8];
PointerTest(b); // で OK

DllImport なアンマネージ関数を呼んでいる最中はこの b の再配置は発生しないので安全
C 側は、バッファサイズを受け取るようにしておかないとバッファオーバーフロー脆弱性発生

[ 親 95956 / □ Tree ] 返信 編集キー/

▲[ 95958 ] / 返信無し
■95959 / 3階層)  Re[3]: C#から「ポインタを引数に持つDLL関数」の呼び方
□投稿者/ taro (8回)-(2020/10/13(Tue) 14:13:33)
No95957 (Hongliang さん) に返信
No95958 (774RR さん) に返信

byte[] でうまくできました。
本当にありがとうございました。
解決済み
[ 親 95956 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -