[英]Calling C++ DLL with a callback function that contains a char* from C#
我有一個C ++ DLL(SimpleDLL.dll),具有暴露的功能(DllFunctionPoibnterGetName),其具有一個函數指針(getNameFP)。 函數指針將char *作為參數(* char * name *)。
// C++
DllExport void DllFunctionPoibnterGetName( void (*getNameFP) (char * name, unsigned short * length ) ) {
char name[1024];
unsigned short length = 0 ;
getNameFP( name, &length );
printf( "length=[%d] name=[%s]\n", length, name );
}
我有一個想要使用這個C ++ DLL的C#應用程序。
// C#
public unsafe delegate void GetName( System.Char* name, System.UInt16* length);
unsafe class Program
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void delegateGetName(System.Char* name, System.UInt16* length);
[DllImport("SimpleDLL.dll", CharSet = CharSet.Ansi )]
public static extern void DllFunctionPoibnterGetName([MarshalAs(UnmanagedType.FunctionPtr)] delegateGetName getName);
static void Main(string[] args)
{
DllFunctionPoibnterGetName(GetName);
}
static void GetName(System.Char* name, System.UInt16* length)
{
// name = "one two three";
*length = 10;
}
}
目前我可以設置長度沒有任何問題,但我似乎無法找到正確設置名稱的方法。
我的問題是
將char *轉換為char []。 這應該夠了吧。
鑄造char不會。 char *數據是“非托管”的本機數據。 C#使用'托管',.NET數據。
您需要為調用創建一個包裝器並使用marschall將數據從“非托管”轉換為“托管”。
您不需要使用不安全的代碼。 你可以這樣做:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void delegateGetName(IntPtr name, out ushort length);
....
static void GetName(IntPtr name, out ushort length)
{
byte[] buffer = Encoding.Default.GetBytes("one two three");
length = (ushort)buffer.Length;
Marshal.Copy(buffer, 0, name, buffer.Length);
}
雖然這種界面設計只是要求緩沖區溢出。 你怎么知道非托管緩沖區有多大? 通過ref
傳遞length
參數會更有意義。 在輸入時它會告訴你緩沖區有多大。 在輸出時,您將記錄您復制到緩沖區的字節數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.