LukeT
LukeT

Reputation: 83

C# DllImport and Marshaling char**

I'm working in c# and I need to use this function from a c++ dll:

extern "C" char   IMPEXP __stdcall service_GetParameter ( const char* parameter, const int value_lenght, char** value );

I have used it in c++ code as follow:

char *val = new char[256];
service_GetParameter("firmware_version", 255, &val);
AnsiString FirmwareVersion = val;
delete[] val;

How can I import this function and use it in c#?

Thanks in advance

Upvotes: 1

Views: 2958

Answers (2)

Medinoc
Medinoc

Reputation: 6608

If this function allocates memory and makes the caller responsible for freeing it, I'm afraid you'll have to manage this manually: Declare the parameter as a ref IntPtr and use the methods of the Marshal class to get a String with a copy of the pointed data.

Then call the appropriate function for freeing the memory (as Dirk said, we can't say more about this without more information on the function).

If it really must be allocated before calling, it should be something looking like this:

[DllImport("yourfile.dll", CharSet = CharSet.Ansi)]
public static extern sbyte service_GetParameter ( String parameter, Int32 length, ref IntPtr val);

public static string ServiceGetParameter(string parameter, int maxLength)
{
    string ret = null;
    IntPtr buf = Marshal.AllocCoTaskMem(maxLength+1);
    try
    {
        Marshal.WriteByte(buf, maxLength, 0); //Ensure there will be a null byte after call
        IntPtr buf2 = buf;
        service_GetParameter(parameter, maxLength, ref buf2);
        System.Diagnostics.Debug.Assert(buf == buf2, "The C++ function modified the pointer, it wasn't supposed to do that!");
        ret = Marshal.PtrToStringAnsi(buf);
    }
    finally { Marshal.FreeCoTaskMem(buf); }
    return ret;
}

Upvotes: 2

DonBoitnott
DonBoitnott

Reputation: 11025

I'd start with something like this:

[DllImport("yourfile.dll", CharSet = CharSet.Ansi]
public static extern Int32 service_GetParameter([MarshalAs(UnmanagedType.LPStr)] String szParameter, Int32 value_length, [Out] StringBuilder sbValue);

Upvotes: 1

Related Questions