Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 904
SaphuA Avatar asked Dec 28 '22 20:12

SaphuA


2 Answers

About your last question:

  • char is a single character.
  • char* is a pointer to a char. If this is interpreted as a string, all data in the memory that follow this memory address will be seen as belonging to the string, up until a value with 0x0 is encountered. Passing a char* into a method means, that this method can change the contents of the string, but not its length.
  • char** is a pointer to a pointer to a char. Passing this to a method means that the method is able to create a new string and return the new address to the caller.
like image 161
Daniel Hilgarth Avatar answered Jan 07 '23 21:01

Daniel Hilgarth


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.

like image 45
Nick Avatar answered Jan 07 '23 21:01

Nick