【问题标题】:IntPtr to three dimensional arrayIntPtr 到三维数组
【发布时间】:2015-07-18 23:32:46
【问题描述】:

我在我的 C# 项目中使用了 C++ dll。使用 pInvoke(平台调用)。

我的 C++ 代码返回一个 double***,而 C# 函数返回一个 IntPtr。

我在两边都有矩阵的尺寸,它们只是不是恒定的。

在 C# 方面我有:

[DllImport("mylib.dll")]
public static extern IntPtr GetMatrix(int width, int height, int depth);

在 C++ 方面我有:

extern "C" {
    __declspec(dllexport) double*** GetMatrix(int width, int height, int depth) {
        // do stuff
        return matrix;
    }
}

现在我需要将此 IntPtr 转换为 double[,,],但是,我不知道该怎么做。

基本上我需要与this question 的答案相反。

【问题讨论】:

  • 您需要了解更多。只知道类型是不够的。您还需要知道尺寸。
  • 我知道两边的尺寸,只是不是恒定的。我编辑了问题...
  • 我解决了这个问题,而不是返回整个矩阵,我只是返回一个双精度。所以是的,我多次调用 DLL。至少这些值是正确的。但我的问题仍然没有解决方案......
  • 问题中缺少什么?
  • 关于如何获取开始尺寸的说明

标签: c# c++ arrays pinvoke intptr


【解决方案1】:

我从未尝试过使用此类数组,但第一个解决方案可能有效,this MSDN article 让我相信:

(请注意,这仅在您可以更改 C# 端的函数定义时才有效)在您的 C# 函数中,将您的 IntPtr 参数更改为 double[,,] 参数并将此 MarshalAs 属性添加到它,类似于上面的MSDN 文章做到了。

[DllImport("FooBar.dll")]
extern void Foo([MarshalAs(UnmanagedType.LPArray, SizeConst=**YOUR ARRAY SIZE HERE**)] double[,,] bar);

这还假设您有一个固定大小的数组,我不确定这将如何与 3d 数组一起工作,但如果您想进一步研究这种类型的解决方案,这里是完整的文档MarshalAsAttribute.


另一个解决方案与另一个问题的反面非常相似。您可以将double[,,] 初始化为您需要的任何大小,然后使用Marshal.Copy (this overload) 开始填充行。您还可以使用相同的功能对单个双精度进行编组。像这样的:

double[,,] arr = new double[25, 25, 200];
int il = arr.GetLength(0), jl = arr.GetLength(1), kl = arr.GetLength(2);

IntPtr values = DllFoo();

for (int i = 0; i < il; i++)
{
    for (int j = 0; j < jl; j++)
    {
        for (int k = 0; k < kl; k++)
        {
            double[] temp = new double[1];
            arr[i,j,k] = Marshal.Copy(values, temp, 1, k + j * jl + k * jl * kl);
        }
    }    
}

您绝对可以从该 sn-p 中获得更多性能,但它仍然可以工作。

【讨论】:

  • 第一个解决方案对我不起作用,因为矩阵的大小不会是恒定的。第二个在 Marshal.Copy 行引发了异常(请求的范围超出了数组的末尾)。而且我确信我将正确的大小值传递给您的函数。
  • 另外,我不得不稍微修改一下,因为 Marshal.Copy 返回 void,我假设应该保存的值是 temp[0],所以 arr[i,j,k] =温度[0]。对吗?
  • 哦,是的,这绝对是它应该的样子。直接在 SO 上写了我所有的代码,所以它从来没有被编译过或任何东西:P
猜你喜欢
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-27
  • 2018-11-27
  • 2012-07-22
  • 1970-01-01
相关资源
最近更新 更多