将托管的c#out变量与非托管的本机c++接口
本文关键字:本机 c++ 接口 变量 c#out | 更新日期: 2023-09-27 18:20:40
背景
大家好。我没有大量的c++经验,但我在其他语言方面有很多经验。
我试图完成的是为一个C#库创建包装器,以便在本机C++应用程序中使用。到目前为止,我所拥有的是一个C++/CLI包装器,它公开了C#库中的许多函数,以便我可以在本机C++应用程序中使用它们。我这样做的方式就像这里展示的一样:
http://pragmateek.com/using-c-from-native-c-with-the-help-of-ccli-v2/
问题
我在将托管C++/CLI指针传递到C#库时遇到问题。C#库中的函数如下所示:
public bool SomeFunction(out byte[] buffer)
由于某种原因,我很难在C++/CLI包装器中传递指向该变量的指针。该函数正在请求托管引用,但是&对托管引用不起作用,而且我似乎也无法通过使用%使其起作用。
我需要从函数中获取字节数组,我非常确定我可以将数据封送为C++代码可以处理的类型。有什么建议吗?
编辑:删除了对C++/CLI代码的不明确引用。作为对Hans的回应,我成功地引用了C#库,因为我已经能够将数据从C#库来回传递到本机C++代码。此外,我不想让这听起来如此神秘。C#库是用于显微镜相机的,我正试图与Micromanager接口。我正在处理的特定函数与从图像缓冲区获取数据有关。
更新
多亏了Lucas,我有了解决方案。无论出于什么原因,我认为我需要将指针传递到我的C++/CLI库中的C#库。我的C++/CLI包装器的最后一个代码是:
public: bool SomeFunction(unsigned char* cBuffer, int* count) {
cli::array<unsigned char>^ buffer;
bool isFull = _referenceToManagedCSharpClass->SomeFunction(buffer);
pin_ptr<unsigned char> pinnedArray = &buffer[0];
cBuffer = pinnedArray;
*count = buffer->Length;
return isFull;
}
现在还不清楚为什么我不需要向C#库传递指针,或者为什么我需要使用pin_ptr将指针存储在cBuffer中,但我想我会通过阅读来解决这个问题。感谢所有帮助我的人。
假设您有以下类:
ref class SomeClass
{
public:
static bool SomeFunction([System::Runtime::InteropServices::OutAttribute] array<unsigned char>^% buffer)
{
buffer = gcnew array<unsigned char> { 'H', 'E', 'L', 'L', 'O' };
return true;
}
};
它可以在C#中实现,这并不重要,只要你可以从C++/CLI访问它(正如Hans所说,添加一个引用)。
要获得输出值,只需执行以下操作:
array<unsigned char>^ clrArray;
SomeClass::SomeFunction(clrArray);
clrArray
将被设置为SomeFunction
从out
参数返回的值。
如果您想从本机C++访问原始字节,您需要pin数组。只要它被固定,就可以安全地引用缓冲区。这里有一个例子:
假设您具有以下本机功能:
void NativeFunc(unsigned char *data, size_t count)
{
std::copy(data, data + count, std::ostream_iterator<unsigned char>(std::cout, ""));
std::cout << std::endl;
}
您可以拨打:
pin_ptr<unsigned char> pinnedArray = &clrArray[0];
NativeFunc(pinnedArray, clrArray->Length);
在pinnedArray
超出范围后,您必须将数据指针视为无效。GC可能会随时对其进行重新定位。如果需要固定更长的时间,请使用固定的GCHandle
,但这更重。