我有一个用C++编写的SDK,用于管理设备。我控制设备的程序是用C#编写的,因此CLI包装器类自然会在两种语言之间进行转换。我的C#项目将包装器作为DLL包含。
我的问题是,C++SDK使用指针指向数据数组。包装器中也提供了这些指针。
包装器。cpp代码:
Wrapper::Wrapper()
{
myData = new DataAquis(); //initiate C++ class's instance
}
int Wrapper::Start()
{
//(..)
int num = myData->Start();
ptr = (myData->img);
return num;
}
此代码初始化设备并创建指向数据结构(无符号字符数组)的指针。
包装器SDK。cpp代码:
int DataAquis::Start()
{
// (...)
// Pointer from SDK
img = pBuffer;
// (...)
return FAILED(nError) ? -1 : 0;
}
包装器。h代码:
public ref class Wrapper
{
public:
Wrapper();
// (...)
unsigned char *ptr;
private:
// (...)
};
代码C#:
public static Wrapper myDataAqui;
// (...)
private static void DataAquisition()
{
// call the start function in wrapper
myDataAqui.Start();
// Unsafe code for pointer use
unsafe
{
// point to aquired data
byte* imgptr1 = myDataAqui.ptr;
// AccesViolationException in above line.
// Data processing
for (y = 0; y < 256; y++)
{
for (x = 0; x < 320; x++)
{
int temp = x * 256 + 255 - y;
Spectrum1.X_Data_brut[bufferIndex][temp] = (UInt16)(*imgptr1++ + *imgptr1++ * 256);
aquirData[temp] = Spectrum1.X_Data_brut[bufferIndex][temp];
}
}
// (...)
}
}
如图所示,在将包装器指针转换为本地字节指针的那一行触发AccessViolationException。
如果我在那一行上放置一个断点,我可以看到包装器指针正确地指向了一个内存地址,但表示它是
无法读取内存
,因此不会在C#中收集指向的数据。
我已经读到,C++中无符号字符的C#等价物是一个字节,因此通常我应该读取相同数量的数据,并且永远不要超出数据结构的边界。
可能有用的其他信息:
-
此项目已从另一台电脑上复制,该电脑上的代码与此相同。
-
两台PC都有相同的Visual Studio,相同。Net版本,相同的SDK,都是64位编译的。只有Windows版本不同(在Windows 8上工作而不在Windows 7上工作)。
-
我尝试使用封送处理函数失败。
你有什么办法来解决这个问题吗?