我正在构建一个使用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#引用标识符,或者即使需要手动指针编组也是如此。如果你们其中一个人能指出我正确的方向,我将永远感激。
答案 0 :(得分:0)
我终于找到了我的问题的解决方案,并且正在为需要澄清的人发布这个:
首先,正如大卫指出的那样,只需将引用的参数视为指针并为其指定数组的地址就行不通了。您必须将整个数组内容复制到引用的数组中。轻松修复。
第二个错误是在C#方法签名中;这里需要的描述是" [Out]",用括号与简单的" out"相比较(再次感谢大卫)。
所以,最终的结果是:
结构不会改变,但C#中的函数签名会:
[DllImport(@"Elemission.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void getResults([Out] intensityType[] graphData);
以下是函数调用的片段:
int arraySize;
DllMethods.executeAcquisition(out arraySize); // arraySize is the Struct array length
intensityType[] resultData = new intensityType[arraySize];
DllMethods.getResults(resultData);
同时在C ++中,包装器接收C#调用并传递给成员函数...
__declspec(dllexport) void getResults(intensitytype* graphData)
{
MainControl::getInstance()->getCamera()->getResults(graphData);
}
......并且看,结构数组已经填满。
void CameraControl::getResults(intensitytype* graphData)
{
for (int i = 0; i < _spectroDataLength; i++)
graphData[i] = _spectroData[i];
}