There is no need to use unsafe to pass a pointer to an array from a DLL. Here is an example (see the "Results" parameter). The key is to use the ref attribute. It also shows how to transfer several other types of data.
As defined in C ++ / C:
#ifdef __cplusplus extern "C" { #endif #ifdef BUILDING_DLL #define DLLCALL __declspec(dllexport) #else #define DLLCALL __declspec(dllimport) #endif static const int DataLength = 10; static const int StrLen = 16; static const int MaxResults = 30; enum Status { on = 0, off = 1 }; struct Result { char name[StrLen];
As used in C #:
private const int DataLength = 10; private const int StrLen = 16; private const int MaxThreatPeaks = 30; public enum Status { on = 0, off = 1 }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct Result { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = StrLen)] public string name;
Without the extern "C" part extern "C" ++ compiler would distort the export name depending on the compiler. I noticed that the name of the EntryPoint / Exported function is the same as the function name in a 64-bit DLL, but when compiled into a 32-bit DLL it has the added "@ 32" (the number may change). Run dumpbin /exports dllname.dll to find the exported name. In some cases, you may also need to use the DLLImport parameter ExactSpelling = true . Note that this function is declared by __stdcall . If it was not specified, that would be __cdecl , and you would need CallingConvention.Cdecl .
Here's how to use it in C #:
Status status = Status.on; double[] data = { -0.034, -0.05, -0.039, -0.034, -0.057, -0.084, -0.105, -0.146, -0.174, -0.167}; Result[] results = new Result[MaxResults]; int nResults = -1;
jtbr
source share