C++封装函数 输入参数是bool,返回值也是bool,给C#调用
C++代码
extern "C" __declspec(dllexport) bool Add1(bool d, bool e) { return d; }
C#代码
[DllImport("ConsoleApplication1.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public static extern bool Add1(bool d, bool e);
或者
[DllImport("ConsoleApplication1.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool Add1([MarshalAs(UnmanagedType.I1)] bool d, [MarshalAs(UnmanagedType.I1)] bool e);
调用
bool a= Add1(true, false); bool a1 = Add1(false, true);
为什么会有代码区别?但是我用的VS2019,实际结果没有区别
[return: MarshalAs(UnmanagedType.I1)] 的作用是告诉 .NET 运行时,C++ 函数返回的 bool 值只占 1 个字节,运行时应该从返回地址(如 AL/RAX 寄存器或栈上)读取 1 个字节,然后将其转换为 C# 的 bool(true/false)。
[MarshalAs(UnmanagedType.I1)] 是 .NET 中用于 自定义平台调用(P/Invoke)或 COM 互操作时数据封送行为 的特性。它告诉运行时:当将托管代码中的某个数据传递给非托管代码(或反向传递)时,应该以 1 字节有符号整数 的形式来表示。
为什么需要它?
默认情况下,C# 中的 bool 类型封送为非托管代码中的 BOOL(即 Windows 中的 4 字节 int,TRUE=1,FALSE=0)。而 C++ 中的原生 bool 类型通常只占 1 字节(值为 0 或 1)。如果直接用默认封送,两者大小不匹配,会导致:
-
数据错位(尤其是结构体布局)
-
调用失败或结果错误
此时就需要 [MarshalAs(UnmanagedType.I1)] 显式指定“这个布尔值要用 1 字节形式传递”,以匹配 C++ 的 bool。
UnmanagedType.I1 的含义
-
UnmanagedType枚举定义了托管数据在非托管端的表示形式。 -
I1代表 有符号 1 字节整数(对应 C/C++ 中的signed char)。

浙公网安备 33010602011771号