如何实现c++返回char**值传给C#

本篇内容主要讲解“如何实现c++返回char**值传给C#”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何实现c++返回char**值传给C#”吧!

创新互联公司长期为成百上千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为细河企业提供专业的网站设计、网站建设,细河网站改版等技术服务。拥有10余年丰富建站经验和众多成功案例,为您定制开发。

char **arr; 
int arrlen,arrcol;
template
void make2DArray(T** &ptr, int rows, int cols)
{
	//创建二维数组,先创建行指针
	ptr = new T*[rows];
	//再为每一行分配空间
	for (int i = 0; i < rows; i++)
	{
		ptr[i] = new T[cols];
	}
}
void alloc2D()
{
	arrlen = 3;
	arrcol = 2;
	arr = new char*[arrlen];//分配3个元素的数组空间,每个元素是char*指针元素
	for (int i = 0; i <= arrlen; i++)
	{
		arr[i] = new char[arrcol*(i+1)+1]; //其实不同行可以长度不同
	}
}

void* returnpptr(int* len) //C++分配内存,返回**给C# 
{
	alloc2D();
	*len = 3;
	for (int i = 0; i < arrlen; i++)
	{
		for (int j = 0; j <= arrcol*(i + 1)+1; j++)
		{
			if (j == arrcol*(i + 1)+1)
				arr[i][j] = 0;
			else
				arr[i][j] = (char)(0x31 + i + j % 5);
		}
	}
	return arr;
}
[DllImport("dllfordebugdemo.dll", EntryPoint = "returnpptr", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr returnpptr(ref int len);
        private void button7_Click(object sender, EventArgs e)
        {
            int len =0;
            IntPtr p = returnpptr(ref len); 
            IntPtr[] ps = new IntPtr[len];
            for(int i =0;i

显示如下:

123
23456
3456734

如果C++返回的是int**,实验如下:

int** ppcol;
int* p1;
int reflen;
void* returnpptrint(int* len)
{
	reflen = 1;
	*len = reflen;
	arrcol = 2;
	p1 = &arrcol;
	if (ppcol == NULL)
	{
		ppcol = &p1;
	}
	return ppcol;
}
[DllImport("dllfordebugdemo.dll", EntryPoint = "returnpptrint", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr returnpptrint(ref int len);
private void button7_Click(object sender, EventArgs e)
        {
            int len =0;
            IntPtr p = returnpptrint(ref len);
            IntPtr[] ps = new IntPtr[len];
            int[] lens = new int[len];
            for (int i = 0; i < len; i++)
            {
                ps[i] = Marshal.ReadIntPtr(p + Marshal.SizeOf(typeof(IntPtr)) * i);
                Marshal.Copy(ps[i],lens,0,1);
                Console.WriteLine("lens[i]=" + lens[i]);
            }

        }

显示:

lens[i]=2

总结:

C#无法接收C++返回值的char**/int**,只能先强转为void*,然后在C#中public static extern IntPtr fun(...),实际使用时二级指针的行数,并且通过IntPtr[]数组和Marshal.ReadIntPtr(基址+偏址),再用Marshal.Copy或PtrToString...方式获取最终值。

到目前为止:三级指针不管是参数还是返回值形式,都不成功(估计还是以后有时间再做实验)。

上面统一以c# IntPtr接收C++的void*(实际是char**/int**强转而来),虽然实验成功,但换种思维方式,c++中还是char**/int** fun(...),而c#中以IntPtr fun(...)可不可以呢?
 

[DllImport("dllfordebugdemo.dll", EntryPoint = "returnpptr", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr returnpptr(ref int len);

private void button7_Click(object sender, EventArgs e)
        {
            int len =0;
            IntPtr p = returnpptr(ref len);
            IntPtr[] ps = new IntPtr[len];
            for (int i = 0; i < len; i++)
            {
                ps[i] = Marshal.ReadIntPtr(p + Marshal.SizeOf(typeof(IntPtr)) * i);
                Console.WriteLine(Marshal.PtrToStringAnsi(ps[i]));
            }
}
void** returnpptr(int* len) //C++分配内存,返回**给C#
{
	alloc2D();
	*len = 3;
	for (int i = 0; i < arrlen; i++)
	{
		for (int j = 0; j <= arrcol*(i + 1)+1; j++)
		{
			if (j == arrcol*(i + 1)+1)
				arr[i][j] = 0;
			else
				arr[i][j] = (char)(0x31 + i + j % 5);
		}
	}
	return (void**)arr;
}
或者将返回值改为实际的char**:
char** returnpptr(int* len) //C++分配内存,返回**给C#
{
	alloc2D();
	*len = 3;
	for (int i = 0; i < arrlen; i++)
	{
		for (int j = 0; j <= arrcol*(i + 1)+1; j++)
		{
			if (j == arrcol*(i + 1)+1)
				arr[i][j] = 0;
			else
				arr[i][j] = (char)(0x31 + i + j % 5);
		}
	}
	return (arr;
}

C#中还是IntPtr returnpptr(ref int len),最终实验也是成功的。

到此,相信大家对“如何实现c++返回char**值传给C#”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!


当前标题:如何实现c++返回char**值传给C#
本文路径:http://myzitong.com/article/gjdepj.html