我有一些非托管C ++动态库和C#GUI应用程序,使用它。我需要将已知大小的字符串数组传递给C ++库,然后填充它。还有最大字符串长度值:
// C++ part
#define MAX_SOME_STRING_LEN 250;
MYDLL_API uint8_t __stdcall getSomeStrings(wchar_t** strings, uint64_t count) {
/// populate strings, not more characters then MAX_SOME_STRING_LEN for each string
return 0;
}
// C# part
[DllImport("biosec_lib.dll", CallingConvention = CallingConvention.StdCall)]
static extern Byte getSomeStrings(string[] providers, UInt64 size);
我想避免在C ++库端进行数组内存管理。我通过其他库API调用获得了理想的字符串数组大小。然后在C#端分配合适的数组并调用此API方法,传递合适的数组。
答案 0 :(得分:0)
这是一种不同的方法。您应该分配一种“非托管”缓冲区,传递给DLL然后转换结果并释放缓冲区。它与C语言完全相同,但是从托管环境调用。
您的DLL的签名将类似于:
[DllImport("biosec_lib.dll", CallingConvention = CallingConvention.StdCall)]
static extern Byte getSomeStrings(IntPtr buffer, UInt64 size);
要从C#调用它,你应该这样做:
IntPtr unmanagedBuffer = Marshal.AllocHGlobal(100);
// Your Unmanaged Call
getSomeStrings(unmanagedBbuffer, 100);
string yourString = Marshal.PtrToStringUni(unmanagedBuffer);
Marshal.FreeHGlobal(unmanagedBuffer);
如果您不希望应用中出现内存泄漏,请不要忘记致电FreeHGlobal。在“try / finally”子句中保护它很有意思。
答案 1 :(得分:0)
如果您想在托管方使用IntPtr,可以这样使用:
[DllImport("biosec_lib.dll", CallingConvention = CallingConvention.StdCall)]
static extern Byte getSomeStrings([In][Out] [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] String[] providers, UInt64 count);