如何将 IStream(C++) 转换为 System::IO::Stream(c#),反之亦然

Posted

技术标签:

【中文标题】如何将 IStream(C++) 转换为 System::IO::Stream(c#),反之亦然【英文标题】:How to convert IStream(C++) to System::IO::Stream(c#) and vice versa 【发布时间】:2019-11-18 11:27:48 【问题描述】:

我有 2 个库,一个是 c++,另一个是 c#。

C++ 库名称->LibA

C#名称->LibB

在 LibA 中,将有 2 个主要 API:

    Serialize-> Serialize API 将使用给定的输入生成 IStream 作为输出。 Deserialize-> Deserialize API 将 IStream 作为输入并反序列化流并从中获取实际数据。
#pragma once
struct GPosition

    double x;
    double y;
    double z;
;
struct GUnitVector

    double x;
    double y;
    double z;
;
struct GLine

    GPosition m_rootPoint;    /* Point on the line, should be in region of interest */
    GUnitVector m_direction;    /* Gradient */
    double m_start;        /* Parameter of start point, must be <= m_end */
    double m_end;          /* Parameter of end point */
;



class GraphicSerializer

public:

    GUID objectID;

    uint32_t aspectID;
    uint32_t controlFlag;
    vector<const GLine *> geomVector;

    void Serialize(IStream &pStream);
    void Deserialize(IStream* pStream);
;

在 LibB 中,将有 4 个 API:

    Object GetObjectFromStream(Stream s)-> 将流作为输入反序列化并返回Objects PutToDB(Object A)-> 将给定对象持久化到 DB Stream GetStreamFromObject(Object a)-> 将对象作为输入序列化并返回。 Object GetFromDB(objectID)->根据id从DB中获取对象
public class CommonBase
    
        public Guid id  get; set; ;
        public byte[] Bytes  get; set;  //contains aspect, control flag, vec<GLine>
    ;

    public interface IGraphicRepository
    
        CommonBase Get(Guid guid);
        bool Put(CommonBase graphic);
    

    public static class GraphicStreamUtility
    
        public static CommonBase GetCommonBaseFromStream(Stream stream);
        public static void SerializeCommonBaseToStream(CommonBase obj, Stream stream);
    

现在我正在编写 C++/CLI 以在 libB 中使用由 libA 生成的流,反之亦然。这样我就可以在 DB 中持久化和检索对象。

谁能告诉我如何将 IStream 转换为 .Net Stream 和 .Net 流转换为 IStream。

【问题讨论】:

【参考方案1】:
Stream^ CGDMStreamCLI::ConvertIStreamToStream(IStream *pStream)

    ULARGE_INTEGER ulSize;
    IStream_Size(pStream, &ulSize);
    size_t size = ulSize.QuadPart;
    auto buffer = std::make_unique<char[]>(size);
    ULONG numRead;
    HRESULT hr = pStream->Read(buffer.get(), size, &numRead);

    if (FAILED(hr) || size != numRead)
    
        throw std::exception("Failed to read the stream");
    

    cli::array<Byte>^ byteArray = gcnew cli::array<Byte>(numRead+2);

    // convert native pointer to System::IntPtr with C-Style cast
    Marshal::Copy((IntPtr)buffer.get(), byteArray, 0, numRead);

    return gcnew System::IO::MemoryStream(byteArray);

【讨论】:

以上是关于如何将 IStream(C++) 转换为 System::IO::Stream(c#),反之亦然的主要内容,如果未能解决你的问题,请参考以下文章

将 QT 资源转换为 ::std::istream&

从 C++ 中的 istream 对象读取时如何检测空行?

将字符串或char *转换为istream的最佳方法?

将 boost`s bufferstream 转换为 istream

将字节数组从 C# 传递到 C++ DLL 作为 char*

在 Windows 中将 FILE * 或 HANDLE 转换(分配)到 IStream