PInvoke and char**

Multi tool use
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?





You could try to replace char with IntPtr and call PtrToStringAuto for the pointer: Marshal.PtrToStringAuto(@out)
– Centro
May 12 '11 at 8:56






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.

aStOpmibIoHwN6pcL2MELS9KlfaMfC,z6g,2pFJ2 G34Rxzucb,buClcV1xHe
c,sviT i0IguW7B lsEp,hf,0U

Popular posts from this blog

PHP contact form sending but not receiving emails

Do graphics cards have individual ID by which single devices can be distinguished?

Create weekly swift ios local notifications