![](/img/trans.png)
[英]Loading a native unmanaged C++ DLL into a managed C# app causes the DLL to output garbage
[英]Interfacing managed c# out variable to unmanaged, native C++
背景
大家好。 我沒有大量的 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 交互的顯微鏡相機。 我正在處理的特定功能與從圖像緩沖區中獲取數據有關。
更新
感謝盧卡斯,我有一個解決方案。 無論出於何種原因,我認為我需要在我的 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++ 訪問原始字節,則需要固定數組。 只要它被固定,您就可以安全地引用緩沖區。 下面是一個例子:
假設您具有以下本機功能:
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
,但這是更重量級的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.