I’m using DllImport to call the functions of C++ from C#.
#if defined(__cplusplus)
extern "C" {
#endif
__declspec(dllexport) int __stdcall ABC(int i);
__declspec(dllexport) char* __stdcall C(int i);
#if defined(__cplusplus)
}
#endif
int __stdcall ABC(int i)
{
return i;
}
char* __stdcall C(int i)
{
char* n = new char[i];
memset(n, 9, i);
return n;
}
Code in C# is:
using System.Runtime.InteropServices;
using System;
namespace DepartmentStore
{
class Exercise
{
[DllImport("library.dll")]
public static extern int ABC(int i);
[DllImport("library.dll")]
public static extern char* C(int i);
static int Main()
{
int k = ABC(10);
byte[] b = C(1024);
return 0;
}
}
}
The function ABC(int i) is OK, but the function C(int i) yielded the following error when building:
“Pointers and fixed size buffers may only be used in an unsafe context”
I guess that I didn’t understand how to export a pointer return of functions.
May Someone please tell me the correct way C# invokes functions with the return type as a pointer?
The P/Invoke later doesn’t know how to marshal C-style arrays from the unmanaged to the managed side; unlike
SAFEARRAY, there is no information embedded in C-style arrays that the P/Invoke later can use to determine how many bytes should be copied.Because of this, you’ll want to declare your
Cfunction to return anIntPtrand then call theMarshal.PtrToStrAnsimethod to convert the pointer to a string on the managed side like so:Additionally, you’ll have to pass the
IntPtrback to the unmanaged side to deallocate the memory that you allocated withnew; if you don’t you’ll have a memory leak.An easier option is to create a managed wrapper for your unmanaged library in C++ that exposes managed functions which make the calls and perform the conversion to a
String^(usingmarshal_as) like so:If you didn’t want to marshal back a
string, and instead marshal back abytearray, then I’d still recommend the wrapper approach (although in this case, it requires you to have some specific knowledge in order to create the managed array to return):These are better options than handling it in managed code completely, as you don’t have to worry about continuously marshalling between managed and unmanaged to handle pointers to memory allocated in the unmanaged space.