侧边栏壁纸
博主头像
Tony's Blog博主等级

行动起来,coding

  • 累计撰写 83 篇文章
  • 累计创建 58 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录
c#

C#调用C++

Tony
2024-02-20 / 0 评论 / 0 点赞 / 5 阅读 / 6493 字

本文链接: https://blog.csdn.net/lishuangquan1987/article/details/103294092

参数类型的调用方法

1. 参数为基本类型,例如int, float, char等

[C++]

void fun(int value);
void fun(float vaue);
void fun(char ch);

[C#]

[DllImport("xxx.dll")]
public static extern void fun(Int32 value);
[DllImport("xxx.dll")]
public static extern void fun(float value);
[DllImport("xxx.dll")]
public static extern void fun(char ch);

2. 参数为基本类型 + 指针, 例如int*, float*, char* 等

[C++]

void fun(int* value);
void fun(float* vaue);
void fun(char* ch);

[C#]

[DllImport("xxx.dll")]
public static extern void fun(ref Int32 value);
[DllImport("xxx.dll")]
public static extern void fun(ref float value);

参数为char*,在C#中有几种实现方式

A. public static extern void fun(string ch); //ch内容不会改变

B. public static extern void fun(StringBuilder ch); //ch内容会改变

3. 参数为结构体

[C++]

struct point
{
	int value;			//基本类型
	char ch;			//基本类型
	int number[100];	//数组
	char buffer[100];	//字符串数组
};
void fun(point pt);

[C#]

[StructLayout(LayoutKind.Sequential)]
public struct point
{
	public Int32 value;
	public char ch;
	[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
	public Int32[] number;
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
	public char[] buffer;
}
[DllImport("xxx.dll")]
public static extern void fun(point pt);

4. 参数为结构体指针

[C++]

void fun(point* pt);

[C#]

[DllImport("xxx.dll")]
public static extern void fun(ref point pt);

5. 参数为结构体, 并且结构体还嵌套结构体

[C++]

struct point
{
	int value;			//基本类型
	char ch;			//基本类型
	int number[100];	//数组
	char buffer[100];	//字符串数组
	struct point pt;	//嵌套结构体
};
void fun(point pt);

[C#]

[StructLayout(LayoutKind.Sequential)]
public struct point
{
	public Int32 value;
	public char ch;
	[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
	public Int32[] number;
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
	public char[] buffer;
	public point pt;
}
[DllImport("xxx.dll")]
public static extern void fun(point pt);

6. 参数为结构体, 并且结构体还嵌套结构体指针或者双指针

[C++]

struct point
{
	int value;			//基本类型
	char ch;			//基本类型
	int number[100];	//数组
	char buffer[100];	//字符串数组
	struct point* p1;	//嵌套结构体指针
	struct point** p2;	//嵌套结构体双指针
};
void fun(point pt);

[C#]

[StructLayout(LayoutKind.Sequential)]
public struct point
{
	public Int32 value;
	public char ch;
	[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
	public Int32[] number;
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
	public char[] buffer;
	public IntPtr p1;	//使用IntPtr替代嵌套指针
	public IntPtr p2;	//使用IntPtr替代嵌套指针
}
[DllImport("xxx.dll")]
public static extern void fun(point pt);

由于嵌套指针的使用比较复杂,需要借助一些手段才能够确保正常调用DLL方法

[C#]

class Program
{
	[StructLayout(LayoutKind.Sequential)]
	public struct point
	{
		public Int32 value;
		public char ch;
		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
		public Int32[] number;
		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
		public char[] buffer;
		public IntPtr p1;	//使用IntPtr替代嵌套指针
		public IntPtr p2;	//使用IntPtr替代嵌套指针
	}
	[DllImport("xxx.dll")]
	public static extern void fun(point pt);

static void Main(string[] args)
	{
		point pt = new point();
		pt.p1 = Marshal.AllocHGlobal(Marshal.Sizeof(typeof(point)));
		pt.p2 = Marshal.AllocHGlobal((Marshal.SizeOf(typeof(point))) * 2);

		try
		{
			pt.value = 1;

			//实现给p1赋值
			point ptt = new point();
            ptt.value = 1;

            Marshal.StructureToPtr(ptt, pt.p1, false);
			//实现给p2赋值
			//由于双指针不能够直接传值,需要用到中间结构的数组指针
			IntPtr[] ptr = new IntPtr[2];
			ptr[0] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(point)));
			ptr[1] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(point)));

			try
			{
				Marshal.StructureToPtr(ptt, ptr[0], false);
				Marshal.Copy(ptr, 0, pt.p2, 2);

				fun(pt);
				//测试返回的指针值是否正确
				ptt = (point)Marshal.PtrToStructure(pt.p1, typeof(point));
				Marshal.Copy(pt.p2, ptr, 0, 2);
				ptt = (point)Marshal.PtrToStructure(ptr[0], typeof(point));
				ptt = (point)Marshal.PtrToStructure(ptr[1], typeof(point));
			}
			catch(System.Exception e)
			{
				string str = e.Message;
			}
			finally
			{
				Marshal.FreeHGlobal(ptr[0]);
				Marshal.FreeHGlobal(ptr[1]);
			}
		}
		catch(System.Exception e)
		{
			string str = e.Message;
		}
		finally
		{
			Marshal.FreeHGlobal(pt.p1);
			Marshal.FreeHGlobal(pt.p2);
		}
	}
}

7.C++返回值乱码问题:

https://www.cnblogs.com/ligl/p/9952849.html

https://blog.csdn.net/qq\_22889875/article/details/78670172

0

评论区