C++ from C#: C++ function (in a DLL) returning false, but C# thinks it's true!

和自甴很熟 提交于 2019-12-05 01:12:42

Try [return: MarshalAs (UnmanagedType.I1)]. By default, C# interop marshals C# bool as the Win32 BOOL, which is the same as int, while C++ bool is one byte AFAIR. Thus, C#'s default marshaling expects the return value to be a BOOL in the eax register, and picks up some non-zero garbage because C++ bool is returned in al.

Your code snippet as posted cannot work. If this was compiled with a C++ compiler then the function name would be ?Foo@@YA_NXZ and your C# code could never find it. The calling convention is important too, it is not the default (CallingConvention.StdCall) unless you tell the compiler. And somewhere you should have told the linker to export the function.

Start by declaring the exported function so it is compatible with default P/Invoke attributes:

extern "C" __declspec(dllexport) 
bool __stdcall Foo() {
    return false;
}

Next problem is that the C++ compiler uses only one byte to store a bool. The machine code generated for your return statement is:

013D138E  xor         al,al

The P/Invoke marshaller will however assume it is a 32-bit integer and check the value of the eax register. Either declare the return type of the function as int or BOOL or use a [return: MarshalAs(UnmanagedType.U1)] attribute in the C# declaration.

I used signed int.

C++ code

   extern "C" __declspec(dllexport) signed int TestDouble(double* output)
    {   
        *output = 1.3;
        return true;
    }

C# code

 [DllImport("abc.dll", EntryPoint = "TestDouble", CallingConvention = CallingConvention.Cdecl)]
 public static extern bool TestDouble(out double output);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!