Fetching an array of strings from a native DLL





5.00/5 (2 votes)
Fetching an array of strings from a native DLL.
Define a function in native DLL (let say it “Win32Native.dll”) as shown below.
extern "C" __declspec(dllexport) void FetchStringArray( int nCount, char* ppStrArray[])
{
int result = 0;
STRSAFE_LPSTR temp;
size_t cchDest = 40;
const size_t alloc_size = sizeof(char) * 40;
for ( int nI = 0; nI < nCount; nI++ )
{
char *pszFormat = "from DLL >> [returned String %d]";
STRSAFE_LPSTR temp = (STRSAFE_LPSTR)CoTaskMemAlloc( alloc_size );
StringCchPrintfA(temp, cchDest, pszFormat, nI);
CoTaskMemFree( ppStrArray[nI] );
ppStrArray[nI] = (char *) temp;
}
}
Points 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.
- On the native side use
CoTaskMemAlloc()
andCoTaskMemFree()
. - On the managed side use
Marshal.AllocCoTaskMem()
andMarshal.FreeCoTaskMem()
.
Writing the client code (the managed part)
We can simply create a console based application:
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace MarshallingTest
{
class Program
{
[DllImport("Win32Native.dll")]
public static extern void FetchStringArray(int nCount, [In, Out] String[] arrStr);
static void Main(string[] args)
{
int nSize = 10;
String[] arrStr = new String[nSize];
FetchStringArray(nSize, arrStr);
Console.WriteLine("Returned String Array");
for (int nI = 0; nI < nSize; nI++)
{
Console.WriteLine(arrStr[nI]);
}
}
}
}
Point of Interest
- namespace System.Runtime.InteropServices; defines the declarations necessary for Interop operations, like DllImport,
- DllImport defines the DLL entry point.
Compile and execute you will get following output.