我有一个通过串口发送数据的程序。我将我的数据存储在本地char
数组中(必须以这种方式,不能使用托管缓冲区),但是当需要通过调用{{}发送到缓冲区时1}}方法,它不接受指向本机数组的指针作为预期的第一个参数。我可以简单地将naive Write(cli::array<unsigned char^>, ...)
缓冲区的内容复制到托管char
缓冲区,然后将此缓冲区作为第一个参数传递给函数array<unsigned char^>
,但这肯定是耗时的。有没有办法将Write(...)
(或char*
)投射到unsigned char*
,以便我可以避免复制内存内容?
答案 0 :(得分:2)
您无法将无法管理的原生char*
数组投射到array<unsigned char>^
。为此,您必须将数据从一个复制到另一个。如果你真的无法删除非托管缓冲区(我怀疑但我没有看到代码,我不知道你的原因)你可以做的是创建一个托管数组,将它固定并在你的无人函数中使用它:
#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会损害性能(根据我的经验,串口/套接字的开销非常高)。