Returning a BSTR
An easy way to return a
string
from an unmanaged C++ DLL is to use the
BSTR
type.
The following C++ export returns a
BSTR
containing a version
string
:
extern
BSTR
__stdcall
GetVersionBSTR()
return
SysAllocString(L
"
Version 3.1.2"
);
The
.DEF
file is as follows:
LIBRARY
EXPORTS
GetVersionBSTR
The export is imported into the .NET application as follows:
namespace
DemoApp.Model
static
class
ImportLibrary
const
String
DLL_LOCATION =
"
DemoLibrary.dll"
;
[DllImport(DLL_LOCATION, CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.BSTR)]
public
static
extern
string
GetVersionBSTR();
The managed code invokes the imported function as follows:
string
version = Model.ImportLibrary.GetVersionBSTR();
The managed code marshals the
string
as a
BSTR
and frees the memory when it is no longer required.
When calling the export from unmanaged code, the
BSTR
should be freed, and a failure to do so creates a memory leak.
Returning a char *
Marshalling a
char *
return value is more difficult for the simple reason that the .NET application has no idea how the memory was allocated, and hence it does not know how to free it. The safe approach is to treat the return
char *
as a pointer to a memory location. The .NET application will not try to free the memory. This of course has the potential for memory leaks if the managed code allocated the
string
on the heap.
The following C++ export returns a version
string
defined as a
string
literal:
extern
char
*
__stdcall
GetVersionCharPtr()
return
"
Version 3.1.2"
;
The corresponding
.DEF
file is as follows:
LIBRARY
EXPORTS
GetVersionCharPtr
The export is imported into the .NET application as follows:
namespace
DemoApp.Model
static
class
ImportLibrary
const
String
DLL_LOCATION =
"
DemoLibrary.dll"
;
[DllImport(DLL_LOCATION, CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public
static
extern
IntPtr
GetVersionCharPtr();
The managed code invokes the imported function as follows:
IntPtr
intPtr = Model.ImportLibrary.GetVersionCharPtr();
string version = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(intPtr);
Passing a String as a BSTR Parameter
It is very easy to pass a
string
as a parameter using the
BSTR
type.
The following C++ export takes a
BSTR
parameter:
extern
void
__stdcall
SetVersionBSTR(BSTR version)