【发布时间】:2016-11-02 20:03:44
【问题描述】:
我正在构建一个使用 C# GUI 和本机 C++ 逻辑 dll 的光谱应用程序。我试图让 dll 填充从 C# 端通过引用传递的简单 C++ 结构数组。但是,当我尝试打印 [应该被填充的] 数组元素时,我得到 System.NullReferenceExceptions 并且数组元素在内存中被标记为 null。
这里是 C++ 结构定义和方法实现:
typedef struct intensitytype {
unsigned short usEchelleOrder; // echelle order
unsigned short usPixel; // horizontal camera pixel index (unbinned !!)
double dIntensity; // intensity
double dWaveLen; // wave length [nm]
} intensitytype;
void CameraControl::getResults(intensitytype* graphData)
{
graphData = _spectroData; // _spectroData is a pointer to a dynamic intensitytype array.
}
这里是 C# 类的定义和签名
[StructLayout(LayoutKind.Sequential)]
public class intensitytype
{
public ushort usEchelleOrder = 0; // echelle order
public ushort usPixel = 0; // horizontal camera pixel index (unbinned !!)
public double dIntensity = 0; // intensity
public double dWaveLen = 0; // wave length [nm]
}
[DllImport(@"Elemission.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void getResults(bool freeData, out intensitytype[] graphData);
我不确定在这种情况下需要什么类型的 C# 引用标识符,或者即使需要手动指针编组。如果你们中的某个人能指出我正确的方向,我将永远感激不尽。
【问题讨论】:
-
您需要至少一种方法让 .NET 封送处理程序确定您传递的数组的大小。查看
ManageAs和UnmanagedType。顺便说一句,out intensitytype[]在 C++ 中会转换为intensitytype**。 -
这里有很多问题。
getResults是静态的吗?看起来不像。不能 p/invoke 实例方法。我认为 C++struct应该映射到 C# 中的结构。您不希望在 C# 参数中出现out。你想要[Out] intensitytype[] graphData。您需要将已分配缓冲区的长度从 C# 传递给 C++。您的 C++ 代码将数组的地址复制到一个值参数,因此在 C# 端看不到任何内容。当然,您需要复制数组的内容。很多问题需要解决。 -
真相是,C# getResults 调用转到一个 c++ 接口,然后调用 CameraControl 类的 getResults 方法: __declspec(dllexport) void getResults(intensitytype* graphData) { MainControl::getInstance()-> getCamera()->getResults(graphData); }
-
事实是,我现在不知道问题是什么。祝你好运。
标签: c# c++ arrays pinvoke pass-by-reference