none
How to pass binary data from C++ dll to a C# application via Interop? RRS feed

  • Question

  • Hi,

    I have a slight problem with passing binary data from a C++ dll to a C# application and I hope someone over here is able to give me some guidance.

    Some background info:
    I have a C++ dll that extracts a char* of binary data containing an image, e.g. JPG, GIF.

    If the output is written from the C++ dll as shown below, it works. The jpeg file is output correctly.

    FILE*  pJPGFile = fopen("E:\\test.jpg","wb");
    fwrite(myBinaryData,1,size_h,pJPGFile);
    fclose(pJPGFile);

    However, when I tried to "send" this block of data to a C# application, the byte array (the datatype I'm using on the C# end) doesn't have the complete data.

    _declspec(dllexport) bool GetImageInfo( BYTE* imageData )
    {
        //..some processing
        imageData = (BYTE*) myBinaryData;
    }



    In my C# portion, I tried the following.

    [DllImport( "MyCPP.dll" , ExactSpelling = true )]
    private static extern bool GetImageInfo( [In,Out] IntPtr imageData);

    private void RunThis()
    {
    byte[] buffer = new byte[ MyIMAGESIZE ];

    GCHandle gc = GCHandle.Alloc( buffer, GCHandleType.Pinned );
    IntPtr imagePtr = gc.AddrOfPinnedObject();

    GetImageInfo( imagePtr );

    System.IO.File.WriteAllBytes("E:\\testcs1.jpg", buffer);
    gc.Free();
    }

    And this:

    private void RunThis2()
    {
    byte[] buffer = new byte[ MyIMAGESIZE ];

    IntPtr imagePtr = Marshal.AllocHGlobal( MyIMAGESIZE );

    GetImageInfo( imagePtr );

    Marshal.Copy( imagePtr, buffer, 0, MyIMAGESIZE );

    System.IO.File.WriteAllBytes("E:\\testcs2.jpg", buffer);

    Marshal.FreeHGlobal( imagePtr );
    }


    Both methods above do not work. I hope someone can really help me here.

    Thanks.
    Knave.







    Monday, October 9, 2006 7:23 AM

Answers

  • It doesn't work because the C++ code doesn't copy the image data, it just overwrites the pointer that your C# passes in. You need to do something like

    memcpy(imageData, myBinaryData, MyIMAGESIZE);

    instead. I would recommend passing in the buffer size as an additional parameter unless you know that it's constant.

     

    Monday, October 9, 2006 9:52 AM
    Moderator

All replies

  • It doesn't work because the C++ code doesn't copy the image data, it just overwrites the pointer that your C# passes in. You need to do something like

    memcpy(imageData, myBinaryData, MyIMAGESIZE);

    instead. I would recommend passing in the buffer size as an additional parameter unless you know that it's constant.

     

    Monday, October 9, 2006 9:52 AM
    Moderator
  • Thanks for the help.

    Yup that is precisely the answer. I tried both of my C# methods and it works after the memcpy call is added to the c++ code.

    btw, the buffersize is obtained from another interop call accessing the same file, so the filesize is already provided.

    Knave
    Wednesday, October 11, 2006 4:57 PM
  • Hi Mattias Sjögren and Knave,

    Thanks a lot for this solution. And it worked like anything... super!!!!!!!!!

    Thanks & Regards,
    Saran
    Wednesday, July 1, 2009 3:22 PM