Search code examples
c#c++streamc++-cli

How to convert IStream(C++) to System::IO::Stream(c#) and vice versa


I have 2 libraries one is c++ and the other one c#.

Name of C++ library->LibA

Name of C#->LibB

In LibA, 2 main APIs will be there:

  1. Serialize-> Serialize API will generate IStream as output with the given inputs.
  2. Deserialize-> Deserialize API will take IStream as input and deserializes the stream and gets actual data from it.
#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);
};

In LibB, 4 APIs will be there:

  1. Object GetObjectFromStream(Stream s)-> Takes stream as input and deserializes it and returns Objects
  2. PutToDB(Object A)-> persists the given object to DB
  3. Stream GetStreamFromObject(Object a)-> Takes object as input serializes it and returns it.
  4. Object GetFromDB(objectID)-> Gets the object from DB based on id
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);
    }

Now I'm writing C++/CLI to use stream generated by libA in libB and vice versa. So that I can persist and retrieve the objects to and from DB.

Can anyone please let me know how to convert IStream to .Net Stream and .Net stream to IStream.


Solution

  • 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);
    }