Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Fetching buffer of numeric types from a native DLL

0.00/5 (No votes)
15 Aug 2013 1  
Fetching buffer of numeric types from a native DLL.

Define some functions in native DLL (let's say it “Win32Native.dll”) as shown below. These three functions receives integer buffer, and double buffer, respectively.

extern "C" __declspec(dllexport) int FetchIntegerArray ( int nNewSize, int** ppnArray );
extern "C" __declspec(dllexport) double  FetchDoubleArray ( int nNewSize, double ** ppnArray );

Implementing Functions

extern "C" __declspec(dllexport) int FetchIntegerArray ( int nNewSize, int** ppnArray ) 
{ 
  int result = 0; 
  //    CoTaskMemAlloc must be used because code on the managed side will call 
  //    Marshal.FreeCoTaskMem to free this memory. 
  int* newArray = (int*)CoTaskMemAlloc( sizeof(int) * nNewSize); 
  for ( int j = 0; j < nNewSize ; j++ ) 
  { 
       newArray[j] = ( j + 1 ) * 10 ; 
       result += newArray[j]; 
   }
  if ( *ppnArray != NULL ) CoTaskMemFree( *ppnArray ); 
  *ppnArray = newArray; 
  return result; 
}
extern "C" __declspec(dllexport) double  FetchDoubleArray ( int nNewSize, double ** ppnArray ) 
{ 
 double result = 0; 
 //    CoTaskMemAlloc must be used because code on the managed side will call 
 //    Marshal.FreeCoTaskMem to free this memory. 
 double* newArray = (double*)CoTaskMemAlloc( sizeof(double) * nNewSize ); 
 for ( int j = 0; j < nNewSize ; j++ ) 
 { 
     newArray[j] = 10 + ( j+1 ) * 30 ; 
     result += newArray[j]; 
 }
 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)

We 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.Runtime.InteropServices; 
using System.Text;
namespace MarshallingTest 
{ 
   class Program 
   { 
       [DllImport("Win32Native.dll")] 
       public static extern int FetchIntegerArray(int nSize, ref IntPtr arrInt); 
       [DllImport("Win32Native.dll")] 
       public static extern double FetchDoubleArray(int nSize, ref IntPtr arrInt);
       static void Main(string[] args) 
       { 
           int nSize = 10; 
           IntPtr ptrArr = IntPtr.Zero;
           int nSum = FetchIntegerArray(nSize, ref ptrArr); 
           int [] arrInt = new int [nSize]; 
           Marshal.Copy(ptrArr, arrInt, 0, nSize);
           Console.WriteLine("\nReturned Integer Buffer\n");
           for (int i = 0; i < nSize; i++) 
           { 
               Console.Write("{0:}  ", arrInt[i]); 
           } 
           Console.Write("\nSum of Integer Buffer : {0}\n", nSum ); 
           Marshal.FreeCoTaskMem(ptrArr);
           ptrArr = IntPtr.Zero; 
          double dblSum = FetchDoubleArray(nSize, ref ptrArr); 
          double[] arrDbl = new double[nSize]; 
          Marshal.Copy(ptrArr, arrDbl, 0, nSize); 
          Console.WriteLine("\nReturned Double Buffer\n"); 
          for (int i = 0; i < nSize; i++) 
          { 
              Console.Write("{0:F2}  ", arrDbl[i]); 
          }
          Console.Write("\nSum of Double Double Buffer : {0}\n", dblSum); 
          Marshal.FreeCoTaskMem(ptrArr); 
      } 
   } 
}

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.

image

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here