DllImport and char Marshaling
public static extern IntPtr Ololo([In] char[] arg, ref Int32 n3);
IntPtr
is the wrong return type, as essentially you want to return the string, not a pointer to the string. In C you can use a pointer to your string by using char*
, the equivalent in .NET would be to use use this: [MarshalAs(UnmanagedType.LPStr)]string
. This should marshall the char*
to a string
correctly.
IntPtr
represents a pointer type, which to get your actual string is useless.
Also looks like you should be taking a StringBuilder
into your Marshalled function, and not a char[]
. Then at least you should be getting the correct string to your C function.
Treno1
Updated on June 04, 2022Comments
-
Treno1 almost 2 years
I'm newbie at C# and Marshaling. I need to use my C func in C#, but i have an incorrect return value from C func (or I don't know how to convert it to correct answer).
C source:
#include "main.h" char *Ololo(char *arg, int &n3) { char *szRet; szRet=(char*)malloc(strlen(arg)+1); strcpy(szRet,arg); n3 = strlen(szRet); return szRet; }
C header:
extern "C" __declspec(dllexport) char *Ololo(char *arg, int &n3);
C# source:
class Program { [DllImport(@"F:\Projects\service\dll\testDLL2.DLL", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] public static extern IntPtr Ololo([In] char[] arg, ref Int32 n3); static void Main(string[] args) { string n1 = "ololo"; char[] chars = new char[n1.Length]; chars = n1.ToCharArray(); Int32 n3 = 0; IntPtr result; result = Ololo(chars, ref n3); string n4 = Marshal.PtrToStringUni(result,n3); Console.WriteLine(n4); } }
I've got return something like "o?? ?"
Sorry for bad English
----------------------Solved-----------------------
class Program { [DllImport(@"F:\Projects\service\dll\testDLL2.DLL", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] public static extern IntPtr Ololo([MarshalAs(UnmanagedType.LPStr)]string arg, ref Int32 n3); static void Main(string[] args) { string n1 = "ololo"; Int32 n3 = 0; int n2 = n1.Length; IntPtr result; result = Ololo(n1, ref n3); string n4 = Marshal.PtrToStringAnsi(result, n3); Console.WriteLine(n4); } }
That works fine. In n3 i ve got 5 and in n4 ololo! Thank s for quick answers!
-
Treno1 over 11 yearsI think
IntPtr
is correct becausen3
returns me 1 and intIntPtr
Ive got first letter (o). But why I have
n3` = 1? I think it needs to be 5. Because of that I think
[In] char[] arg` is incorrect. But what is correct? -
Tony The Lion over 11 years@Treno1 your function in .NET will never give you the entire string back if you return
IntPtr
. -
Treno1 over 11 yearsVS 2010 think that
public static extern [MarshalAs(UnmanagedType.LPStr)]string Ololo
is incorrect because of[MarshalAs(UnmanagedType.LPStr)] cannot be in declaration of class , structure or interface
. -
Puppy over 11 yearsIt isn't. You must have failed to copy the DLLImport attribute over, or placed the declaration in the wrong place.
-
Treno1 over 11 yearsSystem.AccessViolationException if I try to
public static extern StringBuilder Ololo(string arg, ref Int32 n3);
andStringBuilder n5 = Ololo(n1, ref n3);