从 const char* 复制到字节数组 C++/c# interop Marshal::Copy
Posted
技术标签:
【中文标题】从 const char* 复制到字节数组 C++/c# interop Marshal::Copy【英文标题】:Copy from const char* to a byte array C++/c# interop Marshal::Copy 【发布时间】:2011-08-04 17:37:30 【问题描述】:我正在尝试通过托管 C++ 的互操作(编组)将图像从 C++ 发送到 C#。 image->getStream()
从字符串中返回 const char*
。
我的 Marshal::Copy
函数出现异常。
在 mscorlib.dll 中发生
'System.AccessViolationException'
类型的未处理异常附加信息:试图读取或写入受保护的内存。这通常表明其他内存已损坏。
我对从const char*
到字节数组的复制做正确的事情吗?我的 dll 是用 VS2010 中设置的 ASCII 字符编译的。
array<System::Byte>^ OsgViewer::getLastImage()
array< Byte >^ byteArray;
m_ImageQueue->lock();
int index = m_ImageQueue->getCurrentImageIndex();
std::shared_ptr<Image> image = m_ImageQueue->getImage(static_cast<unsigned int>(index));
if( image && image->isValid() == true)
int wLen = image->getStreamSize();
char* wStream = const_cast<char*>(image->getStream());
byteArray = gcnew array< Byte >(wLen);
// convert native pointer to System::IntPtr with C-Style cast
Marshal::Copy((IntPtr)wStream ,byteArray , 0, wLen);
m_ImageQueue->unlock();
return byteArray;
Image是一个自制的C++类
class ADAPTER Image
public :
Image();
~Image();
const char* getStream() const;
int getStreamSize();
bool setStringStream(std::ostringstream* iStringStream);
void setIsValid(bool isValid) m_isValid = isValid;
bool isValid() constreturn m_isValid;
std::ostringstream* getOStringStream() return m_StringStream;
private:
std::ostringstream* m_StringStream;
bool m_isValid;
;
【问题讨论】:
Image是什么类型的?没有 getStream() 或 getStreamSize() 的 System.Drawing.Image。我认为你的问题的根源是流不是字节数组。 看上面的代码,我贴的是图片代码 我猜wStream
不是wLen
字节长度。真的不能告诉你有。如果您添加char temp = wStream[wLen-1]
,您是否会遇到访问冲突。
你是对的,它在 temp = wStream[wLen-1] 上崩溃了几次
那么您从 getStream() 返回的 char*
不是 wLen
字节长。您需要了解为什么getStreamSize()
和getStream()
的返回值之间存在差异
【参考方案1】:
我不会使用 Marshal::Copy。既然你在本地有数组,为什么不直接固定它并使用memcpy
?
pin_ptr<Byte> ptrBuffer = &byteArray[byteArray->GetLowerBound(0)];
您现在可以致电memcpy
至ptrBuffer
。
当作用域结束时,固定会自动撤消。
【讨论】:
这样做,它比 Marshal.Copy 快得多,而且根本不应该伤害 GC,正如@AresAvatar 所说,一旦失去范围,它将自动取消固定。 感谢您的回答。我用过memcpy。我直接复制到 byteArray。 memcpy(字节数组,wStream,wLen)。问题是我的 wStream 是一个指向由 ostringstream.str().c_str() 返回的本地 const char* 的指针。我现在没有 str() 返回缓冲区副本!。以上是关于从 const char* 复制到字节数组 C++/c# interop Marshal::Copy的主要内容,如果未能解决你的问题,请参考以下文章
将字节数组从 C# 传递到 C++ DLL 作为 char*