Home > database >  Random results when passing byte array from c DLL to c# client
Random results when passing byte array from c DLL to c# client

Time:09-30

I am passing a byte array from a function inside c DLL to a c# client. I am using a widely suggested method IntPtr pointer in C# and then Marshal.Copy to create byte array in the C# client. When I read the resulting array it seem I am getting random values. No actual values from the DLL are passed.

It seems the IntPnt is pointing at some random memory address?

Here is the code:

C DLL

extern "C" __declspec(dllexport) char*  __stdcall passBytes() {
    cout << "\n passBytes DLL code START \n";

    char bytes[] = { 0x07, 0x08 };
    cout << "bytes array size: " << sizeof(bytes) << endl;
    for (int i = 0; i < sizeof(bytes); i  ) {
        cout << "byte " << i << " = " << (int)bytes[i] << endl;
    }
    
    char* bptr = bytes;
 
    cout << "\n passBytes DLL code END \n";

    return bptr;
}

C# client

namespace sc_client
{
    class Program
    {
        static void Main(string[] args)
        {
           
            const string libname = "C:/work/x64/Release/libMxN.dll";

            [DllImport(libname)]
           
            static extern IntPtr passBytes();
            IntPtr ptr = passBytes();
            byte[] cbytes = new byte[2];
            Marshal.Copy(ptr, cbytes, 0, 2);

            Console.WriteLine("C# client output: ");
            for ( int i = 0; i < cbytes.Length; i  )
            {
                Console.WriteLine("client byte "   i   " = "   (int)cbytes[i]);
            }
        }
    }
}

Outputs ( just relaunched the app 4 times without any modifications in the code) 1. passBytes DLL code START bytes array size: 2 byte 0 = 7 byte 1 = 8

passBytes DLL code END

C# client output: client byte 0 = 176 client byte 1 = 232

2. passBytes DLL code START bytes array size: 2 byte 0 = 7 byte 1 = 8

passBytes DLL code END C# client output: client byte 0 = 144 client byte 1 = 232

3. passBytes DLL code START bytes array size: 2 byte 0 = 7 byte 1 = 8

passBytes DLL code END C# client output: client byte 0 = 176 client byte 1 = 228

CodePudding user response:

Your primary issue appears to be that the char* array is declared locally, and disappears as soon as the function finishes. One way to do this properly is to allocate it on the heap, and make a separate Free function.

But you are far better off just passing in a buffer. I'm not familiar with C very much, but something like this would be your function

extern "C" __declspec(dllexport) void  __stdcall passBytes(char* bytes, int size) {
....

And then in C# you use it like this

const string libname = "C:/work/x64/Release/libMxN.dll";

[DllImport(libname)]
static extern void passBytes([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)][Out] byte[] bytes, int size);

static void Main(string[] args)
{
    byte[] cbytes = new byte[2];
    passBytes(cbytes, cbytes.Length);

    Console.WriteLine("C# client output: ");
    for ( int i = 0; i < cbytes.Length; i  )
    {
        Console.WriteLine("client byte "   i   " = "   (int)cbytes[i]);
    }
}
  • Related