PInvoke and char**

Multi tool use
PInvoke and char**
I got this assembly from someone which I'd like to use in my c# application.
The header looks like this:
int __declspec(dllimport) s2o(WCHAR* filename, char** out, int* len);
I managed to get it partly working, using:
[DllImport("s2o.dll", EntryPoint = "?skn2obj@@YAHPA_WPAPADPAH@Z", CallingConvention = CallingConvention.Cdecl)]
public static extern int s2o(
[MarshalAs(UnmanagedType.LPWStr)]
string filename,
ref char @out,
ref int len
);
And then calling it like this:
char result = null;
int length = 0;
s2o("filepath", ref result, ref length);
It seems to work partly, because 'length' actually gets a value.
Unfortunatly, 'result' stays null.
What should I do to get this working?
Edit:
Ok I managed to get to to work by replacing the char with a IntPtr and then calling 'Marshal.PtrToStringAnsi' like Nick suggested:
string result = Marshal.PtrToStringAnsi(ptr);
However, because of the comments in that same answer I'm a little worried about memory usage. There are no other methods provided in the assembly so how can I clear things up?
Please declare your function in your DLL with extern "C" to disable name mangling. Now to your question. We can't tell you how to call this function until you tell us how the
out
parameter works. Who allocates what? Do you have any documentation for s2o
?– David Heffernan
May 12 '11 at 8:58
out
s2o
@David: I think he's saying it's a 3rd party DLL so he probably can't add extern "C".
– Nick
May 12 '11 at 9:06
It is indeed a 3rd party dll.
– SaphuA
May 12 '11 at 11:25
You could try using either the Marshal.FreeCoTaskMem or FreeHGlobal. But without knowing how the memory is allocated in the DLL it's hard to know what's going to happen!
– Nick
May 12 '11 at 13:54
2 Answers
2
Have a look at the Marshal.PtrToStringAnsi Method.
Or as Centro says in the comment to your question, PtrToStringAuto may be more appropriate.
Copies all characters up to the first
null character from an unmanaged ANSI
string to a managed String, and widens
each ANSI character to Unicode.
Also note that you may be responsible for freeing the memory returned from this function.
How would the managed code free memory allocated in the native code? That could only work if the native code provided a method to free it, exported the allocator, or used the COM allocator.
– David Heffernan
May 12 '11 at 9:02
@David: Yes, you're right. The O.P. would need to look at the docs for the DLL and work out how the memory is expected to be freed.
– Nick
May 12 '11 at 9:04
While PtrToStringAuto works, i don't get the expected result (instead I get lots of chinese characters), so I think something is going wrong. Also, I'm fairly sure 'out' is a char array, so wouldn't I need to do some sort of conversion first?
– SaphuA
May 12 '11 at 11:24
Did you try the Ansi version?
– Nick
May 12 '11 at 12:23
Woohoo, that works! Please see my edit :)
– SaphuA
May 12 '11 at 13:51
About your last question:
char
char*
char*
char**
Another possibility is that
char**
is an array of C strings, e.g. argv
.– David Heffernan
May 12 '11 at 9:35
char**
argv
Thanks for explaining!
– SaphuA
May 12 '11 at 11:24
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
You could try to replace char with IntPtr and call PtrToStringAuto for the pointer: Marshal.PtrToStringAuto(@out)
– Centro
May 12 '11 at 8:56