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);

【2】结构体作为返回值

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>
时间: 2024-10-05 00:50:39

C#调用C++ 平台调用P/Invoke 结构体--输入输出参数、返回值、返出值、结构体数组作为参数【五】的相关文章

C#调用C++ 平台调用P/Invoke 结构体--结构体嵌套【八】

普通的结构体嵌套很简单,C#中直接定义成对应的结构体即可,这里介绍的是嵌套的结构体以指针的方式表达 [1]嵌套结构体指针 C++代码: typedef struct _testStru10Pre { int iVal; }testStru10Pre; typedef struct _testStru10 { testStru10Pre *pPre; long lVal; _testStru10() { pPre = NULL; } }testStru10; EXPORTDLL_API void

C#调用C++ 平台调用P/Invoke 结构体--含有内置数据类型的一维、二维数组、字符串指针【六】

[1]结构体中含有内置数据类型的一维数组 C++代码: typedef struct _testStru3 { int iValArrp[30]; WCHAR szChArr[30]; }testStru3; EXPORTDLL_API void Struct_ChangeArr( testStru3 *pStru ) { if (NULL == pStru) { return; } pStru->iValArrp[0] = 8; lstrcpynW(pStru->szChArr, L&quo

C#调用C++ 平台调用P/Invoke 结构体--内存对齐方式、union封装【七】

[1]内存对齐方式 C++代码: #pragma pack(push) #pragma pack(1) typedef struct _testStru2 { int iVal; char cVal; __int64 llVal; }testStru2; #pragma pack(pop) EXPORTDLL_API void Struct_PackN( testStru2 *pStru ) { if (NULL == pStru) { return; } pStru->iVal = 1; pS

Net调用非托管代码(P/Invoke与C++InterOP) [转]

将 System::String 转换为 wchar_t* 或 char* PtrToStringChars将String转换为本机wchar_t *或char *.由于 CLR 字符串为内部 Unicode,因此这样通常会返回一个 Unicode 宽字符串指针.然后可以将其转换为宽字符串 1 .Net互操作 .Net不能直接操作非托管代码,这时就需要互操作了. 1.1 P/Invoke 许多常用Windows操作都有托管接口,但是还有许多完整的 Win32 部分没有托管接口.如何操作呢?平台调

Linux中的两个经典宏定义:获取结构体成员地址,根据成员地址获得结构体地址;Linux中双向链表的经典实现。

倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offsetof 1.1 offsetof介绍 定义:offsetof在linux内核的include/linux/stddef.h中定义.#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 说明:获得结构体(TYPE)的变量成员(

C#中跨线程的调用的方法--this.invoke

private void button1_Click(object sender, EventArgs e) { Thread thread = new Thread(new ThreadStart(display)); thread.Start(); } private void display() { while (true) { Thread.Sleep(100); this.Invoke(new threadcall(SetText2)); } } int count = 0; publ

用结构体指针指向(-&gt;)或结构体变量加点(.)后不出现结构体成员

今天写代码时遇到这么个问题:用结构体指针指向(->)或结构体变量加点(.)后不出现结构体成员,虽然不影响编写,但效率降低,容易出错. 代码入下: stack.h #ifndef __STACK_H__ #define __STACK_H__ #include<stdlib.h> #include<iostream> using namespace std; #define STACK_DEFAULT_SIZE 10; typedef int ElemType; typedef

用C#.NET调用Java开发的WebService传递int,double问题,出现java无法获得值!

用C#.NET调用Java开发的WebService时,先在客户端封装的带有int属性的对象,当将该对象传到服务器端时,服务器端可以得到string类型的属性值,却不能得到int类型.double和DateTime类型的值(在服务端得到的均为null) 解决办法: VS2005封装WebService引用 用C#.NET调用Java开发的WebService时,先在客户端封装的带有int属性的对象,当将该对象传到服务器端时,服务器端可以得到string类型的属性值,却不能得到int类型.doub

风险评估DNV GL AS Phast v7.11.33.0/海洋结构物强度分析DNV sesam suite 2013海洋结构物强度分析

风险评估DNV GL AS Phast v7.11.33.0/海洋结构物强度分析DNV sesam suite 2013海洋结构物强度分析DNV Phast Risk v6.7-ISO 1DVDDNV Phast v6.7-ISO 1DVD 最新6.7版本 全功能无限制DNV sesam suite 2013 Full 1CD包含新的 DeepC .GeniE和HydroD模块.DNV sesam Genie 2013 Full 1CD(用于评估无航速浮体流体动力性能的计算软件)DNV Soft