【发布时间】:2018-01-17 19:50:52
【问题描述】:
我有一个用 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];
}
}
// (...)
}
}
如图所示,在我将 Wrapper 指针转换为本地字节指针的行处触发了 AccessViolationException。
如果我在该行设置断点,我可以看到 Wrapper 指针正确指向了内存地址,但表示它无法读取内存,因此永远不会收集指向的数据在 C# 中。
我已经读过 C++ 中 unsigned char 的 C# 等价物是一个字节,所以通常我应该读取相同数量的数据,并且永远不要超出我的数据结构的边界。
可能有用的其他信息:
- 此项目已从另一台 PC 复制,相同的代码在该 PC 上运行。
- 两台 PC 具有相同的 Visual Studio、相同的 .Net 版本、相同的 SDK,均编译为 64 位。仅 Windows 版本不同(适用于 Windows 8,不适用于 Windows 7)。
- 我尝试使用 Marshal 函数没有成功。
您有任何解决方法的想法吗?
【问题讨论】:
-
所以人们来这里只是为了投反对票还是他们真的有什么想法?
-
是的,我不明白有人喜欢为 C++/CLI Q 提供的毯子 -1。你能告诉我们'ptr'的声明吗?我想知道您的 Wrapper 中的成员是否需要是 pin_ptr
-
我已经编辑了我的问题
标签: c# visual-studio c++-cli clr