【问题标题】:Access to a row-major parameters in C# from C++ dll从 C++ dll 访问 C# 中的行主要参数
【发布时间】:2020-06-09 08:15:36
【问题描述】:

我尝试将坐标系参数从 C++ dll 访问到我的 C# 项目中。 C++中的函数声明如下:

unsigned int GetUCS(IUnknown* document, unsigned int id, double (&frame)[16]);

我需要有关行主要的帧参数的帮助:

  [Right_x, Up_x, Forward_x, Translation_x]
  [Right_y, Up_y, Forward_y, Translation_y]
  [Right_z, Up_z, Forward_z, Translation_z]
  [0,       0,    0,         1            ]

在我的 C# 项目中,我必须有类似的东西:

  [DllImport("my.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] 
  private static extern uint GetUCS([MarshalAs(UnmanagedType.IUnknown)] object document, uint id, double(frame)?));

接收帧并基于它进行一些 3D 转换。谢谢!

【问题讨论】:

  • 尝试[In, Out] double[] frame 并传递已分配的double[16]。 PS:CharSet = CharSet.Unicode 在这里好像没用。
  • @simon 当然应该是[In, Out] double[,],然后用new double[4, 4]分配它
  • 非常感谢!我会测试你的反应!!
  • C++ 中的一维数组没有“行优先”的定义。也不在 C# 中。用 column + row*width 计算索引是映射它的明显方法,实际上当编译器执行它时会发生什么。事实上,在 C# 中更快的方法是,多维数组在运行时比锯齿状数组丑得多。
  • 双精度是 8 个字节,您正在读取 16 * 8 = 128 个字节的连续内存。如果您将其声明为 double 或 double[] 则没有区别,除非您想将结果直接放入一维数组或二维数组中。结果将是非托管的,因此我将使用 [MarshalAs(UnmanagedType.I8)]double[] 框架

标签: c# c++ pinvoke marshalling


【解决方案1】:

我想我会使用这样的 C# 多维数组:

[DllImport("my.dll", CallingConvention = CallingConvention.Cdecl)] 
private static extern uint GetUCS(
    [MarshalAs(UnmanagedType.IUnknown)] object document, 
    uint id, 
    [In, Out] double[,] frame
);

您可以像这样在 C# 代码中分配数组:

double[,] frame = new double[4, 4];

您同样可以使用分配为new double[16]double[] frame,这将在字面上匹配C++ 代码,但是您将失去在C# 代码中自然访问矩阵的能力。

【讨论】:

  • 非常感谢!!如果我会收到正确的 UCS 参数,我很好奇。带着结果和结论回来!
  • C# 多维数组是连续的,并按行主要顺序排列,所以这将按预期运行
猜你喜欢
  • 1970-01-01
  • 2014-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-11
相关资源
最近更新 更多