Pergunta

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?

Foi útil?

Solução

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.

Outras dicas

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top