1

VC++ Win32 DLL に関数定義があります。

DEMO2_API void ProcessData(char* i_buff, unsigned short i_len, char* o_buf,
unsigned *o_len, unsigned short *errorCode)
{
    __describe (i_buff,&i_len,o_buf,o_len,errorCode);
}

この dll 関数は、ac# アプリケーションによって呼び出されます。呼び出されると、アクセス違反例外が生成されます。

私が見つけた再調査の後、私の問題の原因。

http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/6e843243-baf4-4eb1-8a20-c691ad47762c

しかし、サンプルコードで彼らが何をしているのか正確には理解できませんでした. 誰かが私にそれを説明できますか?

また、メモリを外部に割り当てた後、C# の P/Invoke シグネチャはどうなるでしょうか?

4

2 に答える 2

0

O_len の受け渡しモードをrefではなくoutに変更したところ、動作しました。

素敵な回答とコメントをくださった皆さんに感謝します。これが他のコミュニティメンバーに役立つことを願っています(およびグーグルの人々...)

于 2010-03-13T08:32:42.070 に答える
0

C# は IntPtr を使用して、外部に割り当てられたメモリを表します。C# のポインターと参照は、ガベージ コレクターによって提供されるメモリでのみ使用できます。

System.InteropServices.Marshal クラスは、IntPtr によって表されるネイティブ メモリ領域とやり取りするためのいくつかのメソッドを提供しますが、もちろんそれらはタイプ セーフではありません。

しかし、あなたの関数には、割り当てられたメモリへのポインターを返す可能性のあるものは何もありません。ダブルポインター引数またはポインター戻り値が必要ですが、どちらもありません。

編集して、要求に応じて例を追加します。

// this doesn't work right
void external_alloc_and_fill(int n, int* result)
{
  result = new int[n];
  while (n-- > 0) { result[n] = n; }
}

extern external_alloc_and_fill(int n, int* result)
int a = 5;
fixed (int* p = &a) {
  external_alloc_and_fill(17, p);
  // p still points to a, a is still 5
}

より良い:

// works fine
void external_alloc_and_fill2(int n, int** presult)
{
  int* result = *presult = new int[n];
  while (n-- > 0) { result[n] = n; }
}

extern external_alloc_and_fill2(int n, ref IntPtr result)
int a 5;
IntPtr p = &a;
external_alloc_and_fill2(17, ref p);
// a is still 5 but p is now pointing to the memory created by 'new'
// you'll have to use Marshal.Copy to read it though
于 2010-03-08T16:22:43.360 に答える