opencart网站,wordpress英文别名,什么软件做网站链接,昆明做网站公司有哪些前言C# 可以通过 DllImport 的方式引用 C 类型的 dll。但很多 dll 的参数不会是简单的基础类型#xff0c;而是结构体 struct 。因此就需要在 C# 端定义同样的结构体类型#xff0c;才能实现调用 C 类型 dll。这里例举几种不同的结构体情况#xff0c;以及其对应的解决方案。…前言C# 可以通过 DllImport 的方式引用 C 类型的 dll。但很多 dll 的参数不会是简单的基础类型而是结构体 struct 。因此就需要在 C# 端定义同样的结构体类型才能实现调用 C 类型 dll。这里例举几种不同的结构体情况以及其对应的解决方案。基础调用方式对于一个结构体类型typedef struct DATA{int nNumber;float fDecimal;};在 C# 端就需要定义为[StructLayout(LayoutKind.Sequential)]public struct DATA{public int nNumber;public float fDecimal;}包含字符数组对于一个包含字符数组的结构体类型typedef struct DATA{int nNumber;float fDecimal;char szString[256];};在 C# 端就需要使用 Marshal 设置数据空间大小同时最好定义一个初始化函数与 get 的定义[StructLayout(LayoutKind.Sequential)]public struct DATA{void alloc() {szString new char[256];}string sString {get {int nLength 256;string sData ;for (int i 0; i nLength; i){if (szData[i] \0) break;sData szData[i];}return sData;}}public int nNumber;public float fDecimal;[MarshalAs(UnmanagedType.ByValArray, SizeConst 256)]char[] szString;}包含字符二维数组对于一个包含字符二维数组的结构体类型typedef struct DATA{int nNumber;float fDecimal;char szString[6][256];};在 C# 端同样需要使用 Marshal 设置数据空间大小需要将两个 Size 相乘并定义一个初始化函数。同时在做一个 get 的定义。[StructLayout(LayoutKind.Sequential)]public struct DATA{void alloc() {szString new char[256 * 6];}public string[] sStrings{get {int nSize 6, nLength 256;string[] sDatas new string[nSize];for (int i 0; i nSize; i){for (int j 0; j nLength; j){if (szData[i * nLength j] \0) break;sData szData[i * nLength i];}sDatas[i] sData;}return sDatas;}}public int nNumber;public float fDecimal;[MarshalAs(UnmanagedType.ByValArray, SizeConst 256 * 6)]char[] szStrings;}dll 入参为结构体数组若有一个这样的 C dll 函数定义void FnCall(DATA* datas);// 调用方式DATA datas[10];fnCall(datas);那么在 C# 中要实现等价调用// 首先 Import 函数[DllImport(Module.dll)]public static extern void FnCall(IntPtr pInfo); // 注意入参要定义为指针// 再定义定义结构体数组int nCount 10;DATA datas new DATA[nCount];// 再分配内存空间int nSize Marshal.SizeOf(typeof(DEVICE_INFO));IntPtr Dataptr Marshal.AllocHGlobal(nSize * nCount);// 调用函数FnCall(Dataptr);// 复制数据到结构体中for (int i 0; i nCount; i){IntPtr ptr (IntPtr)((UInt32)Dataptr i * size);datas[i] (DEVICE_INFO)Marshal.PtrToStructure(ptr, typeof(DEVICE_INFO));}// 释放内存空间Marshal.FreeHGlobal(Dataptr);另外如果你要调用的 dll 是非 C 类型 dll而是 C Class。那么我们就可以将其再包装一层转换为 C 类型 dll。例如class Example {public:int MethodCall();};那么就可以编写 C 类型的 dll。extern C {Example* Example_New() {return new Example();}int Example_MethodCall(Example* p) {return p-MethodCall();}void Example_Delete(Example* p) {delete p;}}C# 那边就这样导入[DllImport(Module.dll)]public static extern IntPtr Example_Create();[DllImport(Module.dll)]public static extern int Example_MethodCall(IntPtr value);[DllImport(Module.dll)]public static extern void Example_Delete(IntPtr value);// 调用方式IntPtr p Example_Create();Example_MethodCall(p);Example_Delete(p);至于 C 类型 dll 中其他类型变量在 C# 的对应则可以参考 Microsoft 的 文档 。总结到此这篇关于C#调用C类型dll入参为struct问题的文章就介绍到这了,更多相关C#调用C类型dll入参内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家