2014-12-05 98 views
1

我有一個通過串口發送數據的程序。我將要發送的數據存儲在原生char數組中(它必須以這種方式發送,根本不能使用受控緩衝區),但是當通過調用Write(cli::array<unsigned char^>, ...)方法發送到緩衝區時,它不會接受按預期的方式將指向本地數組的指針作爲第一個參數。我可以簡單地將天真char緩衝區的內容複製到受管理的array<unsigned char^>緩衝區,然後將此緩衝區作爲第一個參數傳遞給函數Write(...),但這肯定是耗時的。有沒有辦法將char*(或unsigned char*)轉換爲array<unsigned char^),以便我可以避免複製內存內容?char *到數組<unsigned char ^>

+0

你有一個'std :: array'的託管指針,或者你有一個託管指針指向'std :: array'嗎?閱讀問題標題和文字並不是很清楚。請顯示一些代碼,比如你的聲明,至少是你嘗試調用的函數的原型。 – 2014-12-05 08:10:13

+0

顯示您的代碼! – 2014-12-05 08:17:28

+0

我想知道爲什麼你不能使用託管緩衝區。你可以簡單地將它釘在內存中並獲得一個指向內容的本地指針。 – 2014-12-05 08:19:28

回答

2

你不能轉換一個unamanged原生char*數組到array<unsigned char>^。爲此,您必須將數據從一個複製到另一個。如果你真的不能刪除非託管緩衝區(我懷疑,但我沒有看到代碼,但我不知道你的理由),你可以做的是創建一個託管數組,並將其固定在你的unamanged函數中:

#pragma unmanaged 

void work_with_native_buffer(char* pBuffer, size_t size) { 
    // Do your unmanaged stuff here 
} 

#pragma managed 

ref class Test { 
public: 
    void DoNativeStuff() { 
     if (_buffer == nullptr) 
      _buffer = gcnew array<unsigned char>(256); 

     pin_ptr<int> pinnedBuffer = &_buffer[0]; 
     char* pBuffer = pinnedBuffer; 
     work_with_native_buffer(pBuffer, _buffer->Length); 
    } 

    void SendData(Stream^ stream) { 
     Debug.Assert(_buffer != nullptr); 

     stream->Write(_buffer, 0, _buffer->Length); 
    } 

private: 
    array<unsigned char>^ _buffer; 
}; 

總之,你有一個託管緩衝區,但你釘住它,它不會被GC重新定位,並且你有一個原生指針來訪問本地函數。您的非託管代碼不會更改,但您將恢復分配的位置。

如果本機代碼在另一個DLL中,你也可以使用封送處理,但IMO會損害性能(在我的經驗中串行端口/套接字的開銷非常高)。

+0

這沒有解決我的問題,因爲我仍然使用託管緩衝區_buffer進行存儲。謝謝你。 – eral 2014-12-05 08:33:12

+0

是的,**是**的重點!你有一個託管緩衝區可以與託管類一起使用,但是你也有一個_unamanged_(!!!)指針來從_unamanaged_代碼訪問該緩衝區。另一種方式(在_unmanaged_中分配,並在託管中使用,只是**不可能**,除非您隱式或明確地創建副本)。如果你擔心性能...停止這樣做,沒有任何區別(理論上來說,分配託管內存的速度更快)。關於編組:請注意,_out_參數(如果您想在非託管世界中分配)將被編組。 – 2014-12-05 08:35:38

+0

你是對的,這個解決方案聽起來並不像我已經嘗試過的那樣。 – eral 2014-12-05 08:39:53

相關問題