Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify whether to take ownership of the marshalled string or not?

suppose I have x.dll in C++ which looks like this

MYDLLEXPORT
const char* f1()
{
   return "Hello";
}

MYDLLEXPORT
const char* f2()
{
   char* p = new char[20];
   strcpy(p, "Hello");
   return p;   
}

Now, suppose I want to use this in C#

[DllImport("x.dll")]
public static extern string f1();

[DllImport("x.dll")]
public static extern string f2();

Is there any way to tell CLR to take strong ownership of the string returned from f2, but not f1? The thing is that the fact that the string returned from f1 will eventually be freed, deleted, or whatever by GC is equally bad with the fact that the string returned from f2 won't. Hope the question was clear. Thanks in advance

like image 854
Armen Tsirunyan Avatar asked Mar 08 '11 20:03

Armen Tsirunyan


1 Answers

If you have any influence at all over the dll implementation, then I strongly suggest you simply don't do it like you showed in your example. Otherwise, please refine the question to mention that constraint.

If you have to return a heap allocated string from the dll, then you should also provide a cleanup function (always good practice when exporting dynamically allocated memory from a dll). You P/Invoke the allocating function with a return of IntPtr and marshal that with one of the Marshal.PtrToString... at http://msdn.microsoft.com/en-us/library/atxe881w.aspx and finish off by calling the cleanup function for the native side of things.

Another way is to use BSTR (example from Marshaling BSTRs in COM/Interop or P/Invoke):

Native:

__declspec(dllexport)
void bstrtest(BSTR *x)
{
    *x = SysAllocString(L"Something");
}

Managed:

[DllImport("mydll.dll")]
extern static void bstrtest(ref IntPtr dummy);

static void Main(string[] args)
{
    var bstr = IntPtr.Zero;
    bstrtest(ref bstr);

    var text = Marshal.PtrToStringBSTR(bstr);
    Console.WriteLine(text);

    Marshal.FreeBSTR(bstr);
}

I just found a similar question on SO: PInvoke for C function that returns char *

like image 176
Johann Gerell Avatar answered Sep 28 '22 03:09

Johann Gerell