Question

I need to call a c++ callback function from c# that returns a String. When I try with the code below the application crashes hard (with a message saying that it may be due to a corruption of the heap).

Here's the c++ code:

static String^ CppFunctionThatReturnsString()
{
    return gcnew String("From C++");
}

void main()
{
    CSharp::CSharpFunction(IntPtr(CppFunctionThatReturnsString));
}

And here's the c# code:

public class CSharp
{
    private delegate string CppFuncDelegate();

    public static void CSharpFunction(IntPtr cppFunc)
    {
        var func = (CppFuncDelegate)Marshal.GetDelegateForFunctionPointer(cppFunc, typeof(CppFuncDelegate));
        func(); // Crash
    }
}

Do I have to do some kind of marshaling magic with the string before returning it?

Était-ce utile?

La solution

Why are you using function pointers in the first place? Just pass an instance of the delegate to the C# code:

C++:

static String^ CppFunctionThatReturnsString()
{
    return gcnew String("From C++");
}

void main()
{
    CSharp::CSharpFunction(new CSharp::CppFuncDelegate(CppFuncThatReturnsString));
}

C#:

public class CSharp
{
    private delegate string CppFuncDelegate();

    public static void CSharpFunction(CppFuncDelegate d)
    {
        d();
    }
}

I think you may need to put CppFuncThatReturnsString inside a class.

Autres conseils

I found the answer on this ten year old page.

c++:

static const char* __stdcall CppFunctionThatReturnsString()
{
    return "From C++";
}

void main()
{
    CSharp::CSharpFunction(IntPtr(CppFunctionThatReturnsString));
}

c#:

public class CSharp
{
    private delegate IntPtr CppFuncDelegate();

    public static void CSharpFunction(IntPtr cppFunc)
    {
        var func = (CppFuncDelegate)Marshal.GetDelegateForFunctionPointer(cppFunc, typeof(CppFuncDelegate));
        Marshal.PtrToStringAnsi(func());
    }
}

That is, pass it as an IntPtr and marshal it into a string on the C# side.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top