Praveen Katiyar' Blog

Learning along the way . . . .

Fetching a byte buffer from a Win32 DLL


Define  a function in native dll (let say it “Win32Native.dll”)  as shown below.

extern "C" __declspec(dllexport) int FetchByteArray ( int nSize, byte** ppnArray )
    int result = 0;
    //    CoTaskMemAlloc must be used instead of the new operator because code on the managed side will call
    //    Marshal.FreeCoTaskMem to free this memory.
    byte* newArray = (byte*)CoTaskMemAlloc( sizeof(byte) * nSize );
    for ( int j = 0; j < nNewSize ; j++ )
        newArray[j] = ( j+1 ) % 255 ;
        result += newArray[j];

    // release the previous buffer, if any allocated.
    if ( *ppnArray != NULL ) CoTaskMemFree( *ppnArray );
    *ppnArray = newArray;
    return result;

Point of Interest
  • CoTaskMemAlloc is used to allocated the memory required.
  • CoTaskMemFree is used to free any previously allocated buffer, if null is passed then, CoTaskMemFree is not called.

If you want to use a heap that is shared between native and managed, it is more common to use the COM heap.

Writing the client code (the managed part)

one can simple create a console base application which can use this dll. let’s name it MarshallingTest.

see the code snippet below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace MarshallingTest
    class Program
        public static extern int FetchByteArray(int nSize, ref IntPtr arrInt);
        static void Main(string[] args)
            int nSize = 10;
            IntPtr ptrArr = IntPtr.Zero;

            int nSum = FetchByteArray(nSize, ref ptrArr);
            byte[] arrByte = new byte[nSize];
            Marshal.Copy(ptrArr, arrByte, 0, nSize);

            Console.WriteLine("\nReturned Buffer\n");

            for (int i = 0; i < nSize; i++)
                Console.Write ( "{0:D2}  ", arrByte[i] );
            Console.Write("\nSum of Buffer : {0}\n", nSum );

Point of Interest
  • namespace System.Runtime.InteropServices;  defines the declarations necessary for Interop operations, like DllImport,
  • DllImport defines the DLL entry point.
  • Marshal.Copy function used to copy buffer from managed buffer to unmanaged buffer and vice versa.
  • Marshal.FreeCoTaskMem frees the memory allocated by native DLL.

compile and execute you will get following output.



July 31, 2013 - Posted by | .NET, CodeProject, Interoperability, Marshaling, Win32 | , , ,

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: