Search code examples
c#pinvokeintptr

Getting the size of the array pointed to by IntPtr


I have a native C++ function that I call from a C# project using pinvoke.

extern "C" _declspec(dllexport) void GetCmdKeyword( wchar_t** cmdKeyword, uint  pCmdNum )
{
 int status = 1;
 int       count     = 0;
 int       i         = 0;

 if( cmdKeyword == NULL )
      return ERR_NULL_POINTER;

 //search command in command list by letter from 'A' to 'Z'
 count = sizeof( stCommandList ) / sizeof( COMMANDLIST ) ;

 for ( i = 0 ; i < count && status != 0; i++ )
 {
      if ( pCmdNum != stCommandList[i].ulCommand )
           continue;
      *cmdKeyword = &stCommandList[i].CommandKeyWord[0];
      status = 0 ;
 }

}

where stCommandList is a strucutre of type COMMANDLIST and CommandKeyWord member is a char array.

To call this function from C#, I need to pass what arguments? cmdKeyword should be populated in a char array or a string on the C# side i.e. I need to copy the contents of the location that ptr is pointing to an int array in C# file. If I knew the length, I could use Marshal.Copy to do the same. How can I do it now? Also, I do not wish to use unsafe. Does Globalsize help in this?


Solution

  • You cannot infer the length from the pointer. The information must be passed as a separate value alongside the pointer to the array.

    I wonder why you use raw IntPtr rather than C# arrays. I think the answer you accepted to your earlier question has the code that you need: Pinvoking a native function with array arguments.


    OK, looking at the edit to the question, the actual scenario is a little different. The function returns a pointer to a null-terminated array of wide characters. Your pinvoke should be:

    [DllImport(...)]
    static extern void GetCmdKeyword(out IntPtr cmdKeyword, uint pCmdNum);
    

    Call it like this:

    IntPtr ptr;
    GetCmdKeyword(ptr, cmdNum);
    string cmdKeyword = Marshal.PtrToStringUni(ptr);