Question

I have a function definition in my 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);
}

This dll function is called by a c# application. When called, it generate access violation exception.

After reasearching i found, the cause for my problem.

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

But could not understand what exactly they are doinng in example code. Can someone explain it so me?

And what would be P/Invoke signature in c# after externally allocating memory?

Was it helpful?

Solution 2

I changed passing mode of O_len to out instead of ref and it works.

Thnaks everyone for giving nice answers and comments. I hope this would be useful for other community members ( plus those googling...)

OTHER TIPS

C# uses IntPtr to represent externally allocated memory. C# pointers and references can only be used with memory provided by the garbage collector.

The System.InteropServices.Marshal class provides some methods for interacting with native memory areas represented by IntPtr, of course they aren't typesafe.

But I don't see anything in your function that could return a pointer to allocated memory. You'd need a double-pointer argument, or a pointer return value, and you have neither.

EDIT to add example as requested:

// 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
}

better:

// 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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top