本篇内容主要讲解“如何实现c++返回char**值传给C#”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何实现c++返回char**值传给C#”吧!
char **arr; int arrlen,arrcol; template<class T> 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<len;i++) { ps[i] = Marshal.ReadIntPtr(p + Marshal.SizeOf(typeof(IntPtr)) * i); Console.WriteLine(Marshal.PtrToStringAnsi(ps[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#”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。