从C#中的双**类型的C ++ dll获取IntPtr []? [英] Get IntPtr[] from double** type of C++ dll in C#?
问题描述
我在C ++ dll中有一个函数,其返回值为2点,如下所示:
I have a function in C++ dll with its return is 2-point, as follows:
#include "stdafx.h"
#include <vector>
using namespace std;
double** _stdcall f(int *n)
{
vector<double> t;
vector<double> X;
int i=0, j=0;
do
{
t.push_back(3*i-4);
X.push_back(2*j);
i++;
j++;
}
while (i<15&&j<90);
*n=i;
double** ret = new double*[2];
for (i=0;i<2;i++)
ret[i]=new double[*n];
for (i=0;i<*n;i++)
{
ret[0][i]=t[i];
ret[1][i]=X[i];
}
return ret;
}
现在,我在C#中声明这个函数如下:
Now, I declare this function in C# as follows:
[DllImport("exDP.dll")]
public static extern IntPtr[] f(ref int n_);
现在,所有C#代码如下:
Now, all of C# code as follows:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
namespace pABC
{
public partial class frmABC : Form
{
[DllImport("exDP.dll")]
public static extern IntPtr[] f(ref int n_);
public frmABC()
{
InitializeComponent();
}
private void cmdOK_Click(object sender, EventArgs e)
{
int n = 0, i;
IntPtr[] ret = new IntPtr[2];
ret = f(ref n);
double[] t = new double[n];
Marshal.Copy(ret[0], t, 0, n);
double[] X = new double[n];
Marshal.Copy(ret[1], X, 0, n);
MessageBox.Show("X[0]= " + X[0].ToString());
}
}
}
我编译好了。当我运行它时,行发生错误:
I compile OK. When I run it, an error occurs at the line:
ret = f(ref n);
即:无法封送'返回值':无效的托管/非托管类型组合。
如何修复它并正确获得结果。谢谢。
That is: Cannot marshal 'return value': Invalid managed/unmanaged type combination.
How to fix it and get the results correctly. Thanks.
推荐答案
我的经验是:永远不要在C ++中分配内存以在C#中使用它。在C#中分配内存并用C ++填充。
你应该重新设计界面。
C +
My experience is: never allocate memory in C++ to use it in C#. Allocate the memory in C# and fill it in C++.
you should redesign the interface.
C+
_stdcall int f(int *n, double*arr);//return code signals sucess/error
在C#
in C#
double[] arrDoubles = new double[4];
int rc = f((n,arrDoubles);
尝试从 f $输入返回值c $ c>作为 IntPtr
而不是 IntPtr []
,然后封送返回值 IntPtr []
,迭代并将每个条目封送到 double []
。
更改
Try to type the return value fromf
as aIntPtr
instead of aIntPtr[]
, then marshal that return value to aIntPtr[]
, iterate over that and marshal each entry to adouble[]
.
Change
[DllImport("exDP.dll")]
public static extern IntPtr[] f(ref int n_);
to
to
[DllImport("exDP.dll")]
public static extern IntPtr f(ref int n_);
然后读取这样的值;
Then read the values like this;
int n = 0, i;
IntPtr ret = f(ref n);
List<double[]> doubleArrays = new List<double[]>();
IntPtr[] intPtrs = new IntPtr[2];
Marshal.Copy(ret, intPtrs, 0, 2);
for(int c = 0; c < intPtrs.Length; ++c) {
double[] array = new double[n];
Marshal.Copy(intPtrs[c], array, 0, n);
doubleArrays.Add(array);
}
IntPtr
可以保留对任何内容的引用,包括双**
来自 C ++ 函数的结果。
希望这有帮助,
Fredrik
The IntPtr
can hold a reference to anything, including the double**
result from the C++ function.
Hope this helps,
Fredrik
这篇关于从C#中的双**类型的C ++ dll获取IntPtr []?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!