Greetings!

I have a win32 native dll (perhaps that's not the correct term - it's basically a C compiled dll) that I'm accessing in C#. The method signature of the C code (not the actual signature in the dll):

char* TestMethod()

I'd like to access the char* as a byte[] in C#. I know how to access the char* as a string in C#:

[DllImport("DLLTest.dll")]
public static extern String ImportedTestMethod();

The main reason I want to do this is because the char* output is encoded in UTF-8. If I get the actual bytes in C# then it's a simple matter to interpret them correctly and store it in the usual UTF-16 C# string.

Any ideas or workarounds? I can convert the C# string (from the above code) to a byte[] and interpret the encoding correctly but that seems very inefficient.

Thank you for your time and assistance :)

I have investigated using an IntPtr: I have no way of knowing the length of the data coming out of the dll method so I can't successfully copy the data to a byte[]. If there was a way to iterate over the data IntPtr provides access to then I would be able to find the string null terminator and copy to content to a byte[].

Is there a way to manipulate IntPtr to get a byte[] of the method output?

The very few times I've needed to do this, I've used an intermediary (written in managed C++).
I used the managed C++ to call and expose the unmanaged function and then call that from C#.

Here is an earlier post describing it.

I have investigated using an IntPtr: I have no way of knowing the length of the data coming out of the dll method so I can't successfully copy the data to a byte[]. If there was a way to iterate over the data IntPtr provides access to then I would be able to find the string null terminator and copy to content to a byte[].

Is there a way to manipulate IntPtr to get a byte[] of the method output?

You can use Marshal.ReadByte to locate the string terminator, along these lines:

int length = -1;
while(Marshal.ReadByte(ptr, ++length) != 0);

Then you can use Marshal.Copy to get the array:

byte[] bytes = new byte[length];
Marshal.Copy(ptr, bytes, 0, length);

And there you have it.

Extra credit: Turn this into a custom marshaler for UTF-8 strings.

commented: Clean, simple answer. Thank you :) +6
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.