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# 的 booltrue/false)。

[MarshalAs(UnmanagedType.I1)] 是 .NET 中用于 自定义平台调用(P/Invoke)或 COM 互操作时数据封送行为 的特性。它告诉运行时:当将托管代码中的某个数据传递给非托管代码(或反向传递)时,应该以 1 字节有符号整数 的形式来表示。

为什么需要它?

默认情况下,C# 中的 bool 类型封送为非托管代码中的 BOOL(即 Windows 中的 4 字节 intTRUE=1,FALSE=0)。而 C++ 中的原生 bool 类型通常只占 1 字节(值为 0 或 1)。如果直接用默认封送,两者大小不匹配,会导致:

  • 数据错位(尤其是结构体布局)

  • 调用失败或结果错误

此时就需要 [MarshalAs(UnmanagedType.I1)] 显式指定“这个布尔值要用 1 字节形式传递”,以匹配 C++ 的 bool

UnmanagedType.I1 的含义

  • UnmanagedType 枚举定义了托管数据在非托管端的表示形式。

  • I1 代表 有符号 1 字节整数(对应 C/C++ 中的 signed char)。

 

posted @ 2026-05-30 14:08  家煜宝宝  阅读(13)  评论(0)    收藏  举报