【问题标题】:Copy from const char* to a byte array C++/c# interop Marshal::Copy从 const char* 复制到字节数组 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() const{return 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() 的返回值之间存在差异

标签: c# c++ c++-cli marshalling


【解决方案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() 返回缓冲区副本!。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-07
  • 2013-01-25
  • 2022-01-13
  • 2012-10-11
  • 2012-04-15
  • 1970-01-01
相关资源
最近更新 更多