2

I have to call a win32 dll function

int func1( int arg1, unsigned char **arg2, int *arg3);

and i need wrapped in c# as

public extern int fuc1(int arg1, out IntPtr arg2, out IntPtr arg3);

and i called it from a c# application as

int arg1;
IntPtr arg2 = IntPtr.Zero;
IntPtr arg3 = IntPtr.Zero;
func1(arg1,out arg2,out arg3);

Is the function declared in the c# wrapper as well as called in C# test app Correct ? Now i need to store the arg2 in a text file. How to do that.

Got answer from Hans and i wrote it in a file using

System.IO.StreamWriter(@Application.StartupPath + "\\Filename.txt");
file.WriteLine(arg2);
file.Close();
Narayan
  • 1,189
  • 6
  • 15
  • 33
  • The last argument is `ref int`. It is unlikely you can pinvoke this function, the string needs to be released after you converted it with Marshal.PtrToStringAnsi(). You can't, this will leak memory. – Hans Passant Dec 21 '12 at 14:21
  • @HansPassant i have a free function in the dll to clear the memory – Narayan Dec 21 '12 at 15:23

2 Answers2

1

You probably need to use the MarshalAs attribute, for example:

public static extern int func1(int arg1, [MarshalAs(UnmanagedType.LPStr)] string arg2, IntPtr arg3);

Check here for documentation:

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshalasattribute.aspx

Lloyd
  • 29,197
  • 4
  • 84
  • 98
  • Thanks for the reply. I forget to mention in the first time that I'm getting the output value in the arg2. Now i'm getting the ouput but I'm missing some bytes in the arg2 – Narayan Dec 21 '12 at 14:06
1

i have a free function in the dll to clear the memory

Then you have a shot at making this work. The function declaration ought to look like this:

[DllImport("foo.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int func1(int arg1, out IntPtr arg2, ref int arg3);

And you'd call it like this:

IntPtr ptr = IntPtr.Zero;
int dunno = 99;
string result = null;

int retval = func1(42, out ptr, ref dunno);
if (retval == success) {
    result = Marshal.PtrToStringAnsi(ptr);
    // etc...
}
if (ptr != IntPtr.Zero) func1free(ptr);

Where "func1free" is the otherwise undocumented function that releases the string.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • This worked, but third argument arg3 is not a reference to arg2. The arg2 and arg3 are the out values. arg2 is the buffervalue and arg3 is the length of the buffer value. – Narayan Dec 22 '12 at 06:55