Marshalling a char** in C#

前端 未结 2 446
别跟我提以往
别跟我提以往 2021-02-08 12:34

I am interfacing with code that takes a char** (that is, a pointer to a string):

int DoSomething(Whatever* handle, char** error);

2条回答
  •  我在风中等你
    2021-02-08 13:04

    You should just be able to use a ref string and have the runtime default marshaller take care of this conversion for you. You can hint the char width on the parameter with [MarshalAs(UnmanagedType.LPStr)] to make sure that you are using 8-bit characters.

    Since you have a special deallocation method to call, you'll need to keep the pointer, like you've already shown in your question's example.

    Here's how I'd write it:

    [DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)] 
    private static unsafe extern int DoSomething(
        MySafeHandle handle, void** error); // byte** should work, too, I'm just lazy
    

    Then you can get a string:

    var errorMsg = Marshal.PtrToStringAnsi(new IntPtr(*error));
    

    And cleanup:

    [DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)] 
    private static extern int FreeMyMemory(IntPtr h);
    
    // ...
    
    FreeMyMemory(new IntPtr(error));
    

    And now we have the marshalled error, so just return it.

    return errorMsg;
    

    Also note the MySafeHandle type, which would inherit from System.Runtime.InteropServices.SafeHandle. While not strictly needed (you can use IntPtr), it gives you a better handle management when interoping with native code. Read about it here: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.aspx.

提交回复
热议问题