Interoperability returning a string from a Win32 DLL





5.00/5 (1 vote)
Returning a string from a Win32 DLL using Interop.
Introduction
Define a function in native DLL (let's call it “Win32Native.dll”) as shown below.
extern "C" __declspec(dllexport) char * GetStringFromDLL()
{
const size_t alloc_size = 128;
STRSAFE_LPSTR result=(STRSAFE_LPSTR)CoTaskMemAlloc(alloc_size);
STRSAFE_LPCSTR teststr = "This is return string From Native DLL";
StringCchCopyA ( result, alloc_size, teststr );
return result;
}
Points of Interest
STRSAFE_LPSTR
is atypedef
ofchar *
StringCchCopy
is a replacement forstrcpy
(with safety). The size, in characters, of the destination buffer is provided to the function to ensure thatStringCchCopyb
does not write past the end of this buffer. has two variants.StringCchCopyA
(ANSI Version)StringCchCopyW
(Unicode/Wide character Version)- 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()
.
- On the native side use
Writing the client code (the managed part)
We can simply 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
{
[DllImport("Win32Native.dll")] public static extern String GetStringFromDLL();
static void Main(string[] args)
{
Console.WriteLine("Line displayed below is returned from a Native DLL");
string strData = GetStringFromDLL();
Console.WriteLine ( "Returned value [" + strData +"]" );
}
}
}
Points 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.