首页 > 代码库 > C#调用C++ 平台调用P/Invoke 结构体--输入输出参数、返回值、返出值、结构体数组作为参数【五】
C#调用C++ 平台调用P/Invoke 结构体--输入输出参数、返回值、返出值、结构体数组作为参数【五】
【1】结构体作为输入输出参数
C++代码:
typedef struct _testStru1 { int iVal; char cVal; __int64 llVal; }testStru1;
EXPORTDLL_API void Struct_Change( testStru1 *pStru ) { if (NULL == pStru) { return; } pStru->iVal = 1; pStru->cVal = 'a'; pStru->llVal = 2; wprintf(L"Struct_Change \n"); }
C#代码:指定为ref即可
/* 1.以StructLayout来标记结构体,指定结构体内存布局 * 2.字段定义的顺序 * 3.字段类型 * 4.字段在内存中的大小 * 5.非托管与托管结构名称可以不同 */ //4.1 结构体作为输入输出参数 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct testStru1 { public int iVal; public sbyte cVal; public long llVal; }; [DllImport("ExportDll.dll", CharSet = CharSet.Unicode)] public static extern void Struct_Change(ref testStru1 pStru);
测试:
CExportDll.testStru1 stru1 = new CExportDll.testStru1(); CExportDll.Struct_Change(ref stru1);
C++代码:
typedef struct _testStru5 { int iVal; }testStru5; testStru5 g_stru5;
EXPORTDLL_API testStru5* Struct_Return() { g_stru5.iVal = 5; wprintf(L"Struct_Return \n"); return(&g_stru5); }
C#代码,定义返回值为IntPtr,再进行解析:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct testStru5 { public int iVal; }; [DllImport("ExportDll.dll", CharSet = CharSet.Unicode)] public static extern IntPtr Struct_Return();
测试:
IntPtr struIntPtr = CExportDll.Struct_Return(); CExportDll.testStru5 stru5 = (CExportDll.testStru5)(Marshal.PtrToStructure(struIntPtr, typeof(CExportDll.testStru5)));
【3】结构体数组作为参数
C++代码:
typedef struct _testStru6 { int iVal; }testStru6;
EXPORTDLL_API void Struct_StruArr( testStru6 *pStru, int len ) { if (NULL == pStru) { return; } for ( int ix=0; ix<len; ix++) { pStru[ix].iVal = ix; } wprintf(L"Struct_StruArr \n"); }
C#代码:定义成testStru6[]即可,如果需要返回修改后的值,则需要指定[In,Out]参数
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct testStru6 { public int iVal; }; [DllImport("ExportDll.dll", CharSet = CharSet.Unicode)] public static extern void Struct_StruArr([In, Out]testStru6[] pStru, int len);
测试:
CExportDll.testStru6 []stru6 = new CExportDll.testStru6[5]; CExportDll.Struct_StruArr(stru6, 5);
【4】结构体作为返出参数,释放非托管的内存
C++代码:
typedef struct _testStru8 { int m; }testStru8;
EXPORTDLL_API void Struct_ParameterOut( testStru8 **ppStru ) { if (NULL == ppStru) { return; } *ppStru = (testStru8*)CoTaskMemAlloc(sizeof(testStru8)); (*ppStru)->m = 8; wprintf(L"Struct_ParameterOut \n"); }
C#代码:定义成ref IntPtr即可,需要解析
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct testStru8 { public int m; }; [DllImport("ExportDll.dll", CharSet = CharSet.Unicode)] public static extern void Struct_ParameterOut(ref IntPtr ppStru);
测试:
<strong>IntPtr outPtr = IntPtr.Zero; CExportDll.Struct_ParameterOut(ref outPtr); CExportDll.testStru8 stru8 = (CExportDll.testStru8)(Marshal.PtrToStructure(outPtr, typeof(CExportDll.testStru8))); Marshal.FreeCoTaskMem(outPtr); </strong>
C#调用C++ 平台调用P/Invoke 结构体--输入输出参数、返回值、返出值、结构体数组作为参数【五】
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。