2015-11-05 79 views
-2

背景接口託管C#out變量非託管,本機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代碼的不清楚引用。爲了迴應漢斯,我成功地引用了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,但我想我會通過閱讀來解決這個問題。感謝所有幫助過我的人。

+0

*你很不清楚爲什麼你發佈了這個方法的C++/CLI聲明。你不應該自己寫它,因爲它存在於C#庫中。您的C++/CLI項目必須添加對C#庫的引用。 –

+0

我很抱歉不清楚。正如我所說的,我對C++相對來說比較陌生。正如我上面所說,我必須編寫一個接口來將C#庫展示給本機C++(不是C++/CLI)。我發佈了C++/CLI,因爲這是我在SDK中給出的參考點,我認爲這是在C++/CLI中公開此特定C#函數的起點(因爲SDK C++/CLI已經是一個很好的開始指向我已經包含的其他功能)。 – FirstPrime

回答

1

假設你有下面的類:

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訪問(添加引用as Hans said)。

要獲得產值,你只需做到以下幾點:

array<unsigned char>^ clrArray; 
SomeClass::SomeFunction(clrArray); 

clrArray將被設置爲從out參數由SomeFunction返回的值。

如果要從本地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,但這更重量級。

+0

我嘗試了第一個定義clrArray的建議,然後將它與C#庫一起使用。我不需要編組(這是因爲數組是cli :: array)以將其轉換爲C++嗎?如果是這種情況,那麼我試圖用循環條目來編組數據的方法不起作用,因爲在嘗試使用clrArray.Count時出現錯誤。我將不得不明天嘗試你最後的方法。我用pin_ptr嘗試了一下它的變體,但我想我可能弄錯了。謝謝您的幫助。 – FirstPrime

+0

你說得對,你不能直接在C++中使用'cli :: array' *。你有兩個解決方案:你可以編組數組(這意味着你將它的內容複製到本地緩衝區),或者你可以像我在答案中那樣獲取一個指向數據的指針。這可以在沒有拷貝開銷的情況下工作,你只需要確保它保持固定。 –

+0

啊,好吧。那我誤解了你的答案。好吧,看起來我使用的是Count而不是Length,當我嘗試這樣的事情時就開始了。我有一個剩餘的問題是爲什麼我不需要傳遞指向C#函數的指針。再次,我對無知表示歉意。 – FirstPrime