从 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)];

您现在可以致电memcpyptrBuffer

当作用域结束时,固定会自动撤消。

【讨论】:

这样做,它比 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*

类数组内部的C++深拷贝const char *?

将 ansichar 数组复制到 char delphi 10.2 数组

C++ 将字符串添加到 const char* 数组

在C++中,如何把字节数组转换成字符串

为啥从 int 到 const char* 的转换会破坏 C++ [重复]