如何通过COM互操作将C++结构体传递给C# DLL方法?
可以实现,具体操作步骤如下
1. 在C#端定义与C++结构体匹配的COM可见结构体
必须保证结构体的内存布局和C端完全一致,同时标记为COM可见。假设你要传递的C结构体包含整数、浮点数和固定长度字符串,C#端的代码修改如下:
using System.Runtime.InteropServices; using System; namespace CommonTest { [ComVisible(true)] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct MyStruct { public int Id; public float Value; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string Name; } [ComVisible(true)] public interface ICommonTest { [DispId(1)] int Test(MyStruct inputStruct); } [ComVisible(true)] public class CommonTestManaged : ICommonTest { public int Test(MyStruct inputStruct) { // 直接访问结构体内容 Console.WriteLine($"收到结构体数据:Id={inputStruct.Id}, Value={inputStruct.Value}, Name={inputStruct.Name}"); return inputStruct.Id; } } }
2. 在C++端定义完全匹配的结构体并调用
C++端的结构体成员类型、顺序、大小必须和C#端严格对应,避免内存错位:
#include <atlbase.h> #include <atlcom.h> #include <cstring> // 导入C#生成的COM类型库(可通过tlbimp工具生成,或在项目中直接添加引用) #import "CommonTest.tlb" raw_interfaces_only // 定义与C#匹配的结构体 struct MyStruct { int Id; float Value; wchar_t Name[20]; }; void Usage() { CoInitialize(nullptr); ICommonTestPtr pICommonTest(__uuidof(CommonTestManaged)); // 初始化结构体数据 MyStruct input; input.Id = 100; input.Value = 3.14f; wcscpy_s(input.Name, L"TestData"); long lResult = 0; // 调用Test方法,传入结构体 pICommonTest->Test(reinterpret_cast<_MyStruct*>(&input), &lResult); CoUninitialize(); }
关键注意事项
- 内存布局必须严格对齐:结构体成员的类型、顺序、字节大小要完全一致,否则会出现内存访问错误或数据乱码。
- 字符集统一:C#端用
CharSet.Unicode时,C++端对应使用wchar_t类型的字符串。 - 复杂类型处理:如果结构体包含指针或嵌套复杂类型,需要改用COM接口或
IntPtr进行封送,不能直接按值传递。 - COM注册:C#项目编译时需勾选"注册COM互操作"(项目属性→生成选项),或手动使用
regasm命令注册生成的DLL。
内容的提问来源于stack exchange,提问作者guyus15
相关产品推荐
相关产品推荐

