{"id":70,"date":"2013-08-03T14:45:29","date_gmt":"2013-08-03T14:45:29","guid":{"rendered":"https:\/\/praveenkatiyar.wordpress.com\/?p=70"},"modified":"2013-08-03T14:45:29","modified_gmt":"2013-08-03T14:45:29","slug":"fetching-buffer-of-numeric-types-from-a-native-dll","status":"publish","type":"post","link":"https:\/\/praveenkatiyar.in\/blog\/index.php\/2013\/08\/03\/fetching-buffer-of-numeric-types-from-a-native-dll\/","title":{"rendered":"Fetching buffer of numeric types from a Win32 DLL"},"content":{"rendered":"<p>Define some functions in native dll (let say it \u201c<strong>Win32Native.dll<\/strong>\u201d)&#160; as shown below. These 3 functions receives integer buffer, and double buffer respectively.<\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><strong><font color=\"#0000ff\">extern &quot;C&quot; __declspec(dllexport) int FetchIntegerArray ( int nNewSize, int** ppnArray );<\/font><\/strong><\/span><\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><strong><font color=\"#0000ff\">extern &quot;C&quot; __declspec(dllexport) double&#160; FetchDoubleArray ( int nNewSize, double ** ppnArray );          <br \/><\/font><\/strong><\/span><\/p>\n<h3>Implementing Functions<\/h3>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><font color=\"#0000ff\"><strong>extern &quot;C&quot; __declspec(dllexport) int FetchIntegerArray ( int nNewSize, int** ppnArray )          <br \/>{           <br \/>&#160;&#160;&#160;&#160;&#160; int result = 0;           <br \/>&#160;&#160;&#160;&#160;&#160; \/\/&#160;&#160;&#160; CoTaskMemAlloc must be used because code on the managed side will call           <br \/>&#160;&#160;&#160;&#160;&#160; \/\/&#160;&#160;&#160; Marshal.FreeCoTaskMem to free this memory.           <br \/>&#160;&#160;&#160;&#160;&#160; int* newArray = (int*)CoTaskMemAlloc( sizeof(int) * nNewSize);           <br \/>&#160;&#160;&#160;&#160;&#160; for ( int j = 0; j &lt; nNewSize ; j++ )           <br \/>&#160;&#160;&#160;&#160;&#160; {           <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; newArray[j] = ( j + 1 ) * 10 ;           <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; result += newArray[j];           <br \/>&#160;&#160;&#160;&#160;&#160;&#160; }<\/strong><\/font><\/span><\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><font color=\"#0000ff\"><strong>&#160;&#160;&#160;&#160;&#160; if ( *ppnArray != NULL ) CoTaskMemFree( *ppnArray );          <br \/>&#160;&#160;&#160;&#160;&#160; *ppnArray = newArray;           <br \/>&#160;&#160;&#160;&#160;&#160; return result;           <br \/>}<\/strong><\/font><\/span><\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><font color=\"#0000ff\"><strong>extern &quot;C&quot; __declspec(dllexport) double&#160; FetchDoubleArray ( int nNewSize, double ** ppnArray )          <br \/>{           <br \/>&#160;&#160;&#160;&#160; double result = 0;           <br \/>&#160;&#160;&#160;&#160; \/\/&#160;&#160;&#160; CoTaskMemAlloc must be used because code on the managed side will call           <br \/>&#160;&#160;&#160;&#160; \/\/&#160;&#160;&#160; Marshal.FreeCoTaskMem to free this memory.           <br \/>&#160;&#160;&#160;&#160; double* newArray = (double*)CoTaskMemAlloc( sizeof(double) * nNewSize );           <br \/>&#160;&#160;&#160;&#160; for ( int j = 0; j &lt; nNewSize ; j++ )           <br \/>&#160;&#160;&#160;&#160; {           <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; newArray[j] = 10 + ( j+1 ) * 30 ;           <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; result += newArray[j];           <br \/>&#160;&#160;&#160;&#160; }<\/strong><\/font><\/span><\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><font color=\"#0000ff\"><strong>&#160;&#160;&#160;&#160; if ( *ppnArray != NULL ) CoTaskMemFree( *ppnArray );          <br \/>&#160;&#160;&#160;&#160; *ppnArray = newArray;           <br \/>&#160;&#160;&#160;&#160; return result;           <br \/>}<\/strong><\/font><\/span><\/p>\n<h4>Point of Interest<\/h4>\n<ul>\n<li><strong>CoTaskMemAlloc is used to allocated the memory required. <\/strong><\/li>\n<li><strong>CoTaskMemFree <\/strong>is used to free any previously allocated buffer, if null is passed then, <strong>CoTaskMemFree <\/strong>is not called<strong>.<\/strong> <\/li>\n<\/ul>\n<p>If you want to use a <strong>heap that is shared between native and managed<\/strong>, it is more common to use the COM heap.<\/p>\n<ul>\n<li>On the native side use <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms692727.aspx\"><code><strong>CoTaskMemAlloc()<\/strong><\/code><\/a> and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms680722.aspx\"><code><strong>CoTaskMemFree()<\/strong><\/code><\/a>. <\/li>\n<li>On the managed side use <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.runtime.interopservices.marshal.alloccotaskmem.aspx\"><code><strong>Marshal.AllocCoTaskMem()<\/strong><\/code><\/a> and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.runtime.interopservices.marshal.freecotaskmem.aspx\"><code><strong>Marshal.FreeCoTaskMem()<\/strong><\/code><\/a>. <\/li>\n<\/ul>\n<h4>Writing the client code (the managed part)<\/h4>\n<p>one can simple create a console base application which can use this dll. let\u2019s name it <strong>MarshallingTest. <\/strong><\/p>\n<p>see the code snippet below.<\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><font color=\"#0000ff\"><strong>using System;          <br \/>using System.Runtime.InteropServices;           <br \/>using System.Text;<\/strong><\/font><\/span><\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><font color=\"#0000ff\"><strong>namespace MarshallingTest          <br \/>{           <br \/>&#160;&#160; class Program           <br \/>&#160;&#160; {           <br \/>&#160;&#160;&#160;&#160;&#160;&#160; [DllImport(&quot;Win32Native.dll&quot;)]           <br \/>&#160;&#160;&#160;&#160;&#160;&#160; public static extern int FetchIntegerArray(int nSize, ref IntPtr arrInt);<\/strong><\/font><\/span> <\/p>\n<p><font color=\"#0000ff\"><strong>&#160;&#160;&#160;&#160;&#160;&#160; [DllImport(&quot;Win32Native.dll&quot;)]        <br \/>&#160;&#160;&#160;&#160;&#160;&#160; public static extern double FetchDoubleArray(int nSize, ref IntPtr arrInt);<\/strong><\/font><\/p>\n<p><font color=\"#0000ff\"><strong>&#160;&#160;&#160;&#160;&#160;&#160; static void Main(string[] args)        <br \/>&#160;&#160;&#160;&#160;&#160;&#160; {         <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int nSize = 10;         <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IntPtr ptrArr = IntPtr.Zero;<\/strong><\/font><\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><font color=\"#0000ff\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int nSum = FetchIntegerArray(nSize, ref ptrArr);          <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int [] arrInt = new int [nSize];           <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Marshal.Copy(ptrArr, arrInt, 0, nSize);<\/strong><\/font><\/span><\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><font color=\"#0000ff\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;\\nReturned Integer Buffer\\n&quot;);<\/strong><\/font><\/span><\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><font color=\"#0000ff\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for (int i = 0; i &lt; nSize; i++)          <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {           <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.Write(&quot;{0:}&#160; &quot;, arrInt[i]);           <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<\/strong><\/font><\/span> <\/p>\n<p><font color=\"#0000ff\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.Write(&quot;\\nSum of Integer Buffer : {0}\\n&quot;, nSum );        <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Marshal.FreeCoTaskMem(ptrArr);<\/strong><\/font><\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><font color=\"#0000ff\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ptrArr = IntPtr.Zero;          <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; double dblSum = FetchDoubleArray(nSize, ref ptrArr);           <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; double[] arrDbl = new double[nSize];           <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Marshal.Copy(ptrArr, arrDbl, 0, nSize);<\/strong><\/font><\/span> <\/p>\n<p><font color=\"#0000ff\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;\\nReturned Double Buffer\\n&quot;);        <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for (int i = 0; i &lt; nSize; i++)         <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {         <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.Write(&quot;{0:F2}&#160; &quot;, arrDbl[i]);         <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<\/strong><\/font><\/p>\n<p><span style=\"font-family:courier new;color:#0000ff;\"><font color=\"#0000ff\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.Write(&quot;\\nSum of Double Double Buffer : {0}\\n&quot;, dblSum);          <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Marshal.FreeCoTaskMem(ptrArr);           <br \/>&#160;&#160;&#160;&#160;&#160; }           <br \/>&#160;&#160; }           <br \/>}<\/strong><\/font><\/span><\/p>\n<h4>Point of Interest<\/h4>\n<ul>\n<li><strong>namespace System.Runtime.InteropServices;<\/strong>&#160; defines the declarations necessary for Interop operations, like <strong>DllImport<\/strong>, <\/li>\n<li><strong>DllImport<\/strong> defines the DLL entry point. <\/li>\n<li><strong>Marshal.Copy<\/strong> function used to copy buffer from managed buffer to unmanaged buffer and vice versa. <\/li>\n<li>Marshal.<strong>FreeCoTaskMem<\/strong> frees the memory allocated by native DLL. <\/li>\n<\/ul>\n<p>compile and execute you will get following output.<\/p>\n<p><a href=\"http:\/\/praveenkatiyar.wordpress.com\/wp-content\/uploads\/2013\/08\/image.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"background-image:none;padding-top:0;padding-left:0;display:inline;padding-right:0;border-width:0;\" border=\"0\" alt=\"image\" src=\"http:\/\/praveenkatiyar.wordpress.com\/wp-content\/uploads\/2013\/08\/image_thumb.png\" width=\"666\" height=\"91\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Define some functions in native dll (let say it \u201cWin32Native.dll\u201d)&#160; as shown below. These 3 functions receives integer buffer, and double buffer respectively. extern &quot;C&quot; __declspec(dllexport) int FetchIntegerArray ( int nNewSize, int** ppnArray ); extern &quot;C&quot; __declspec(dllexport) double&#160; FetchDoubleArray ( int nNewSize, double ** ppnArray ); Implementing Functions extern &quot;C&quot; __declspec(dllexport) int FetchIntegerArray ( int&hellip; <a class=\"more-link\" href=\"https:\/\/praveenkatiyar.in\/blog\/index.php\/2013\/08\/03\/fetching-buffer-of-numeric-types-from-a-native-dll\/\">Continue reading <span class=\"screen-reader-text\">Fetching buffer of numeric types from a Win32 DLL<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,3,9,15],"tags":[28],"class_list":["post-70","post","type-post","status-publish","format-standard","hentry","category-net","category-codeproject","category-interoperability","category-win32","tag-marshaling","entry"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/posts\/70","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=70"}],"version-history":[{"count":0,"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/posts\/70\/revisions"}],"wp:attachment":[{"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=70"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=70"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=70"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}