C# calls C++ dll string type return
For this problem, Baidu has a lot of unreliable information, such as C# calling the c++ type, and using string, StringBuilder, Byte[], etc., but it didn't work.
Actually, it's a very simple question. Let's make a record:
C++ end: (Define the return data as structure Vector4)
struct Vector4 { float A, B, C; const char* D; };
C# end: (received the returned structure Vector4)
[StructLayout()] struct Vector4 { public float A, B, C; public IntPtr D; }
In fact, it's just a simple sentence, just use IntPtr to receive the char* parameter and it's done.
InrPtr: Used to represent a platform-specific type of pointer or handle; after receiving IntPtr data, just perform a data conversion:
//Transfer with Intint i=1; IntPtr p=new IntPtr(i); int ch_i=(int) p; //Transfer with stringstring str="a"; IntPtr p=(str); string s=(p); (p)
C# calls C++ dll type comparison table summary
Function calls cause stack asymmetry.
The reason may be that the managed PInvoke signature does not match the unmanaged target signature. Just add the CallingConvention parameter to the dllimport.
[DllImport(PCAP_DLL, CharSet = , CallingConvention = )]
Pay attention to the correspondence between C++ and data types in NET.
//c++:char * ---- c#:string //Passed in parameters //c++:char * ---- c#:StringBuilder//Passing out parameters //c++:char *Variable name ---- c#:ref string variable name //c++:char *Input variable name ---- c#:string Enter variable name //c++:char *Output variable name ---- c#:[MarshalAs()] StringBuilder output variable name //c++:SHORT(short) ---- c#:System.Int16 //c++:LONG(long) ---- c#:System.Int32 //C#All data type conversion methods collected and sorted by calling C++ DLLs may have duplicate or multiple solutions, test them yourself //c++:HANDLE(void *) ---- c#: //c++:Byte(unsigned char) ---- c#: //c++:SHORT(short) ---- c#:System.Int16 //c++:WORD(unsigned short) ---- c#:System.UInt16 //c++:INT(int) ---- c#:System.Int16 //c++:INT(int) ---- c#:System.Int32 //c++:UINT(unsigned int) ---- c#:System.UInt16 //c++:UINT(unsigned int) ---- c#:System.UInt32 //c++:LONG(long) ---- c#:System.Int32 //c++:ULONG(unsigned long) ---- c#:System.UInt32 //c++:DWORD(unsigned long) ---- c#:System.UInt32 //c++:DECIMAL ---- c#: //c++:BOOL(long) ---- c#: //c++:CHAR(char) ---- c#: //c++:LPSTR(char *) ---- c#: //c++:LPWSTR(wchar_t *) ---- c#: //c++:LPCSTR(const char *) ---- c#: //c++:LPCWSTR(const wchar_t *) ---- c#: //c++:PCAHR(char *) ---- c#: //c++:BSTR ---- c#: //c++:FLOAT(float) ---- c#: //c++:DOUBLE(double) ---- c#: //c++:VARIANT ---- c#: //c++:PBYTE(byte *) ---- c#:[] //c++:BSTR ---- c#:StringBuilder //c++:LPCTSTR ---- c#:StringBuilder //c++:LPCTSTR ---- c#:string //c++:LPTSTR ---- c#:[MarshalAs()] string //c++:LPTSTR Output variable name --- c#:StringBuilder output variable name //c++:LPCWSTR --- c#:IntPtr //c++:BOOL ---- c#:bool //c++:HMODULE ---- c#:IntPtr //c++:HINSTANCE ---- c#:IntPtr //c++: Structure --- c#:public struct {}; //c++: Structure **Variable name --- c#:out variable name //C# declares the variable name after instantiation of a structure in advance //c++: Structure & variable name --- c#:ref structure variable name //c++:WORD ---- c#:ushort //c++:DWORD ---- c#:uint //c++:DWORD ---- c#:int //c++:UCHAR ---- c#:int //c++:UCHAR ---- c#:byte //c++:UCHAR* ---- c#:string //c++:UCHAR* ---- c#:IntPtr //c++:GUID ---- c#:Guid //c++:Handle ---- c#:IntPtr //c++:HWND ---- c#:IntPtr //c++:DWORD ---- c#:int //c++:COLORREF ---- c#:uint //c++:unsigned char ---- c#:byte //c++:unsigned char * ---- c#:ref byte //c++:unsigned char * ---- c#:[MarshalAs()] byte[] //c++:unsigned char * ---- c#:[MarshalAs()] Intptr //c++:unsigned char & ---- c#:ref byte //c++:unsigned char variable name --- c#:byte variable name //c++:unsigned short variable name --- c#:ushort variable name //c++:unsigned int variable name --- c#:uint variable name //c++:unsigned long variable name --- c#:uint variable name //c++:unsigned long variable name --- c#:ulong variable name //c++:char variable name --- c#:byte variable name // A character in C++ is represented by one byte, and a character in C# is represented by two bytes //c++:char array name [array size] --- c#:MarshalAs(, SizeConst = array size)] public string array name; ushort //c++:char * ---- c#:string //Passed in parameters //c++:char * ---- c#:StringBuilder//Passing out parameters //c++:char *Variable name ---- c#:ref string variable name //c++:char *Input variable name ---- c#:string Enter variable name //c++:char *Output variable name ---- c#:[MarshalAs()] StringBuilder output variable name //c++:char ** ---- c#:string //c++:char **Variable name --- c#:ref string variable name //c++:const char * --- c#:string //c++:char[] ---- c#:string //c++:char variable name [array size] ---- c#:[MarshalAs(,SizeConst=array size)] public string variable name; //c++:struct structure name *Variable name --- c#:ref Structure name Variable name //c++:Delegate variable name --- c#:Delegate variable name //c++:int ---- c#:int //c++:int ---- c#:ref int //c++:int & ---- c#:ref int //c++:int * ---- c#:ref int //Before calling in C#, int variable name must be defined = 0; //c++:*int ---- c#:IntPtr //c++:int32 PIPTR * ---- c#:int32[] //c++:float PIPTR * ---- c#:float[] //c++:double** array name --- c#:ref double array name //c++:double*[] array name --- c#:ref double array name //c++:long --- c#:int //c++:ulong ---- c#:int //c++:UINT8 * ---- c#:ref byte //Before calling in C#, byte variable name must be defined = new byte(); //c++:handle ---- c#:IntPtr //c++:hwnd ---- c#:IntPtr //c++:void * ---- c#:IntPtr //c++:void * user_obj_param ---- c#:IntPtr user_obj_param //c++:void * Object name --- c#:([MarshalAs()]Object object name //c++:char, INT8, SBYTE, CHAR ---- c#: //c++:short, short int, INT16, SHORT ---- c#:System.Int16 //c++:int, long, long int, INT32, LONG32, BOOL , INT ---- c#:System.Int32 //c++:__int64, INT64, LONGLONG ---- c#:System.Int64 //c++:unsigned char, UINT8, UCHAR , BYTE ---- c#: //c++:unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR , __wchar_t ---- c#:System.UInt16 //c++:unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT ---- c#:System.UInt32 //c++:unsigned __int64, UINT64, DWORDLONG, ULONGLONG ---- c#:System.UInt64 //c++:float, FLOAT ---- c#: //c++:double, long double, DOUBLE ---- c#: //Win32 Types ---- CLR Type //Struct needs to be CRedfine a Struct in # //CallBack callback function needs to be encapsulated in a delegate, delegate static extern int FunCallBack(string str); //unsigned char** ppImage replaced with IntPtr ppImage //Int& nWidth replaced with ref int nWidth //int*, int&, can be used for ref int //Double-pin refers to type parameters, you can use ref IntPtr //Fun pointer uses c++: typedef double (*fun_type1)(double); corresponding to c#:public delegate double fun_type1(double); //char*'s operation c++: char*; corresponding to c#:StringBuilder; //cUse pointers in #: add unsafe where you need to use pointers //Unsigned char corresponds to public byte /* * typedef void (*CALLBACKFUN1W)(wchar_t*, void* pArg); * typedef void (*CALLBACKFUN1A)(char*, void* pArg); * bool BIOPRINT_SENSOR_API dllFun1(CALLBACKFUN1 pCallbackFun1, void* pArg); * The call method is * [UnmanagedFunctionPointer()] * public delegate void CallbackFunc1([MarshalAs()] StringBuilder strName, IntPtr pArg); * */
The above is personal experience. I hope you can give you a reference and I hope you can support me more.