[英]Strange Issues Trying to Pass uint8_t* from C# to C++
I am having major issues working with a third-party API from C#. 我在使用C#的第三方API时遇到重大问题。 I do not have the full source code for this API, nor do I know how the DLL was compiled. 我没有此API的完整源代码,也不知道DLL是如何编译的。 I have been trying for many, many hours to figure this out to no avail. 我已经尝试了许多小时,以解决这个问题。
As far as I can tell, the function in question is defined in C++ as such: 据我所知,有问题的函数在C ++中的定义如下:
extern "C" uint32_t __stdcall GetQHYCCDSingleFrame(qhyccd_handle *handle,
uint32_t *w, uint32_t *h, uint32_t *bpp, uint32_t *channels, uint8_t *imgdata);
The trouble-object in question is uint8_t *imgdata
. 有问题的故障对象是uint8_t *imgdata
。 It is intended to be an array of 8-bit integers, passed by reference to the function. 它打算是一个8位整数数组,通过引用传递给该函数。 In C++, I declare the object as such: 在C ++中,我这样声明该对象:
ImgData = (unsigned char *)malloc(length);
memset(ImgData,0,length);
before passing it to the above function. 在将其传递给上述功能之前。
In C#, I have tried a few different methods of passing the imgdata
object correctly, but all result in similar issues. 在C#中,我尝试了几种正确传递imgdata
对象的方法,但是所有方法都会导致类似的问题。 For example, I have declared a byte array in C# as: byte[] ImgData = new byte[length]
. 例如,我在C#中将字节数组声明为: byte[] ImgData = new byte[length]
。 The GetQHYCCDSingleFrame
function is imported into C# using the following declaration: 使用以下声明将GetQHYCCDSingleFrame
函数导入C#:
[DllImport("qhyccd.dll", EntryPoint = "GetQHYCCDSingleFrame")]
public static extern UInt32 GetQHYCCDSingleFrame(IntPtr handle, ref UInt32 w, ref UInt32 h, ref UInt32 bpp, ref UInt32 channels, byte[] rawArray);
I can call the function properly without errors, but I run into issues when trying to use the ImgData
array in C#. 我可以正确调用该函数而不会出现错误,但是在尝试在C#中使用ImgData
数组时遇到了问题。 In particular, say that I would like to print each element in the array to the console using the following code snippet: 特别是,我想使用以下代码片段将数组中的每个元素打印到控制台:
for (int i = 0; i < length; i++)
{
Console.WriteLine(Convert.ToString(ImgData[i]));
}
This appears to run until about the 84,000th element, at which point a pop-up occurs telling me that "Application has stopped working", with no other error information. 这似乎一直运行到第84,000个元素为止,这时会出现一个弹出窗口,告诉我“应用程序已停止工作”,没有其他错误信息。 I can access that element just fine, but if I want to write each element to a .CSV file, looping will always crash my program with no error information. 我可以很好地访问该元素,但是如果我想将每个元素写入.CSV文件,则循环将始终使程序崩溃,并且没有错误信息。 To make things even stranger the following code snippet will work: 为了使事情变得更加陌生,以下代码片段将起作用:
byte safeByte;
for (int i = 0; i < length; i++)
{
safeByte = rawArray[i];
}
which indicates to me that it's not necessarily a memory-access issue. 这向我表明这不一定是内存访问问题。 And, finally, to make things even more confusing, this code snippet will crash with the same "Application has stopped working" popup: 最后,为了使事情更加混乱,此代码段将与相同的“应用程序已停止工作”弹出窗口崩溃:
byte safeByte;
byte[] newArray = new byte[length];
for (int i = 0; i < length; i++)
{
safeByte = rawArray[i];
}
except that it will crash while declaring the newArray
object, before even entering the loop. 除了在进入循环之前,在声明newArray
对象时它将崩溃。
I have tried many solutions from stackoverflow questions similar to mine, but nothing has worked, and I will always get the same "Application has stopped working" popup. 我已经从类似于我的stackoverflow问题中尝试了许多解决方案,但是没有任何效果,并且我将始终得到相同的“应用程序已停止工作”弹出窗口。 I really just need to save this data somehow to a text file in its integer form. 我真的只需要将数据以某种整数形式保存到文本文件中。
Without access to the library itself, it's hard to provide direct help. 如果无法访问库本身,则很难提供直接帮助。 However, interop problems can often be resolved by creating a shim, then contracting the shim's code into non-existence once the shim is working. 但是,互操作性问题通常可以通过以下方式解决:创建垫片,然后在垫片工作后将垫片的代码压缩为不存在。 An added benefit to this approach is that it splits the problem into more manageable chunks, and makes it easier to ask for focused help if stuck. 这种方法的另一个好处是,它可以将问题分成更易于管理的部分,并且如果遇到困难,可以更轻松地寻求重点帮助。
How to solve C#/C++ interop problems via shimming: 如何通过填充解决C#/ C ++互操作问题:
The above code works, but when I change the parameter from classA to classB, line 5 causes a crash with the error message "error: foo". 上面的代码有效,但是当我将参数从classA更改为classB时,第5行导致崩溃,并显示错误消息“错误:foo”。 I thought this change was OK because of ZZZ. 由于ZZZ,我认为此更改可以。 How can I add a classB parameter without this crash? 如何在没有崩溃的情况下添加classB参数?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.