Pankaj Parag
Pankaj Parag

Reputation: 437

Marshalling LPWSTR * from a C function

I have a sample function from a native code

HRESULT getSampleFunctionValue(_Out_ LPWSTR * argument)

This function outputs the value in argument. I need to call it from the Managed code

[DllImport("MyDLL.dll", EntryPoint = "getSampleFunctionValue", CharSet = CharSet.Unicode)]
static extern uint getSampleFunctionValue([MarshalAsAttribute(UnmanagedType.LPWStr)] StringBuilder  argument);

This returns garbage value. AFAIK the original C function does not create string using CoTaskMemAlloc. What is the correct call?

Any help will be appreciated.

Upvotes: 2

Views: 2971

Answers (1)

David Heffernan
David Heffernan

Reputation: 613582

You need the C# code to receive a pointer. Like this:

[DllImport("MyDLL.dll")]
static extern uint getSampleFunctionValue(out IntPtr argument);

Call it like this:

IntPtr argument;
uint retval = getSampleFunctionValue(out argument);
// add a check of retval here
string argstr = Marshal.PtrToStringUni(argument);

And you'll also presumably need to then call the native function that deallocates the memory that it allocated. You can do that immediately after the call to Marshal.PtrToStringUni because at that point you no longer need the pointer. Or perhaps the string that is returned is statically allocated, I can't be sure. In any case, the docs for the native library will explain what's needed.

You may also need to specify a calling convention. As written, the native function looks like it would use __cdecl. However, perhaps you didn't include the specification of __stdcall in the question. Again, consult the native header file to be sure.

Upvotes: 4

Related Questions