c++类型与c#类型匹配

//c++:HANDLE(void   *)                          ----    c#:System.IntPtr
//c++:Byte(unsigned   char)                     ----    c#:System.Byte
//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#:System.Decimal
//c++:BOOL(long)                                ----   c#:System.Boolean
//c++:CHAR(char)                                ----   c#:System.Char
//c++:LPSTR(char   *)                           ----   c#:System.String
//c++:LPWSTR(wchar_t   *)                       ----    c#:System.String
//c++:LPCSTR(const   char   *)                  ----    c#:System.String
//c++:LPCWSTR(const   wchar_t   *)              ----    c#:System.String
//c++:PCAHR(char   *)                           ----    c#:System.String
//c++:BSTR                                      ----   c#:System.String
//c++:FLOAT(float)                              ----    c#:System.Single
//c++:DOUBLE(double)                            ----    c#:System.Double
//c++:VARIANT                                   ----   c#:System.Object
//c++:PBYTE(byte   *)                           ----    c#:System.Byte[]

//c++:BSTR                                      ----   c#:StringBuilder
//c++:LPCTSTR                                   ----   c#:StringBuilder
//c++:LPCTSTR                                   ----    c#:string
//c++:LPTSTR                                    ----    c#:[MarshalAs(UnmanagedType.LPTStr)] string
//c++:LPTSTR 输出变量名                         ----    c#:StringBuilder 输出变量名
//c++:LPCWSTR                                   ----    c#:IntPtr
//c++:BOOL                                      ----    c#:bool 
//c++:HMODULE                                   ----    c#:IntPtr  
//c++:HINSTANCE                                 ----    c#:IntPtr
//c++:结构体                                    ----    c#:public struct 结构体{};
//c++:结构体 **变量名                           ----    c#:out 变量名  //C#中提前申明一个结构体实例化后的变量名
//c++:结构体 &变量名                            ----    c#:ref 结构体 变量名
//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(UnmanagedType.LPArray)] byte[]
//c++:unsigned char *                           ----    c#:[MarshalAs(UnmanagedType.LPArray)] Intptr

//c++:unsigned char &                           ----    c#:ref byte
//c++:unsigned char 变量名                      ----    c#:byte 变量名
//c++:unsigned short 变量名                     ----    c#:ushort 变量名
//c++:unsigned int 变量名                       ----    c#:uint 变量名
//c++:unsigned long 变量名                      ----    c#:ulong 变量名

//c++:char 变量名                               ----    c#:byte 变量名   //C++中一个字符用一个字节表示,C#中一个字符用两个字节表示
//c++:char 数组名[数组大小]                     ----   c#:MarshalAs(UnmanagedType.ByValTStr, SizeConst         =         数组大小)]        public string 数组名; ushort

//c++:char *                                    ----   c#:string       //传入参数
//c++:char *                                    ----   c#:StringBuilder//传出参数
//c++:char *变量名                              ----    c#:ref string 变量名
//c++:char *输入变量名                          ----    c#:string 输入变量名
//c++:char *输出变量名                          ----    c#:[MarshalAs(UnmanagedType.LPStr)] StringBuilder 输出变量名

//c++:char **                                   ----    c#:string
//c++:char **变量名                             ----    c#:ref string 变量名
//c++:const char *                              ----    c#:string
//c++:char[]                                    ----    c#:string
//c++:char 变量名[数组大小]                     ----    c#:[MarshalAs(UnmanagedType.ByValTStr,SizeConst        =        数组大小)] public string 变量名;

//c++:struct 结构体名 *变量名                   ----    c#:ref 结构体名 变量名
//c++:委托 变量名                               ----    c#:委托 变量名

//c++:int                                       ----    c#:int
//c++:int                                       ----    c#:ref int
//c++:int &                                     ----    c#:ref int
//c++:int *                                     ----    c#:ref int      //C#中调用前需定义int 变量名         =         0;

//c++:*int                                      ----    c#:IntPtr
//c++:int32 PIPTR *                             ----    c#:int32[]
//c++:float PIPTR *                             ----    c#:float[]
      

//c++:double** 数组名                           ----    c#:ref double 数组名
//c++:double*[] 数组名                          ----    c#:ref double 数组名
//c++:long                                      ----    c#:int
//c++:ulong                                     ----    c#:int
      
//c++:UINT8 *                                   ----    c#:ref byte       //C#中调用前需定义byte 变量名         =         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 * 对象名称                           ----    c#:([MarshalAs(UnmanagedType.AsAny)]Object 对象名称

      
//c++:char, INT8, SBYTE, CHAR                               ----    c#:System.SByte
//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#:System.Byte
//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#:System.Single
//c++:double, long double, DOUBLE                                               ----    c#:System.Double

//Win32 Types                                                                  ----  CLR Type
      

//Struct需要在C#里重新定义一个Struct
//CallBack回调函数需要封装在一个委托里,delegate static extern int FunCallBack(string str);

//unsigned char** ppImage替换成IntPtr ppImage
//int& nWidth替换成ref int nWidth
//int*, int&, 则都可用 ref int 对应
//双针指类型参数,可以用 ref IntPtr
//函数指针使用c++: typedef double (*fun_type1)(double); 对应 c#:public delegate double fun_type1(double);
//char* 的操作c++: char*; 对应 c#:StringBuilder;
//c#中使用指针:在需要使用指针的地方 加 unsafe


//unsigned   char对应public   byte


WORD                                ushort
DWORD                 uint
UCHAR                 int/byte               大部分情况都可以使用int代替,而如果需要严格对齐的话则应该用bytebyte
UCHAR*                 string/IntPtr
unsigned char*      [MarshalAs(UnmanagedType.LPArray)]byte[]/?(Intptr)
char*                 string
LPCTSTR             string
LPTSTR                 [MarshalAs(UnmanagedType.LPTStr)] string
long                     int
ulong               uint
Handle                 IntPtr
HWND                     IntPtr
void*                 IntPtr
int                      int
int*                     ref int
*int                     IntPtr
unsigned int        uint
COLORREF            uint

Wtypes.h 中的非托管类型    非托管C 语言类型     托管类名           说明
HANDLE                     void*                System.IntPtr      32 位
BYTE                       unsigned char        System.Byte        8 位
SHORT                      short                System.Int16       16 位
WORD                       unsigned short       System.UInt16      16 位
INT                        int                 System.Int32       32 位
UINT                       unsigned int         System.UInt32      32 位
LONG                       long                System.Int32       32 位
BOOL                       long                System.Int32       32 位
DWORD                      unsigned long        System.UInt32      32 位
ULONG                      unsigned long        System.UInt32     32 位
CHAR                       char                System.Char        用 ANSI 修饰。
LPSTR                      char*                System.String 或 System.StringBuilder  用 ANSI 修饰。
LPCSTR                     Const char*          System.String 或 System.StringBuilder  用 ANSI 修饰。
LPWSTR                     wchar_t*             System.String 或 System.StringBuilder  用 Unicode 修饰。
LPCWSTR                    Const wchar_t*       System.String 或 System.StringBuilder  用 Unicode 修饰。
FLOAT                      Float               System.Single     32 位
DOUBLE                     Double               System.Double     64 位
 
C/C++中的结构类型数据在C#下的转换
 
在做项目移植的时候,经常会碰到数据类型的转换,而我这一次碰到的是C/C++中的结构怎样转换到C#。折腾了一个晚上终于有一个完美的方案。
例如我们在C/C++下的结构数据如下:

typedef struct
{
    char  sLibName[ 256 ];
    char  sPathToLibrary[ 256 ];
    INT32       iEntries;
    INT32       iUsed;
    UINT16     iSort;
    UINT16     iVersion;
    BOOLEAN     fContainsSubDirectories;
    INT32       iReserved;
} LIBHEADER;

我们想把它转成C#下的结构类型如下:
    public struct LIBHEADER
    {
        public char[] sLibName;
        public char[] sPathToLibrary;
        public Int32 iEntries;
        public Int32 iUsed;
        public UInt16 iSort;
        public UInt16 iVersion;
        public Boolean fContainsSubDirectories;
        public Int32 iReserved;
    }
      
看上去好像没问题了,呵呵呵,其实这样是不行的,我们得再给C#编译器一些信息,告诉它一些字符数组的大小。然后它们在C#下面长得样子就变成这样:
    [StructLayout(LayoutKind.Sequential)]
    public struct LIBHEADER
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
        public char[] sLibName;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
        public char[] sPathToLibrary;
        public Int32 iEntries;
        public Int32 iUsed;
        public UInt16 iSort;
        public UInt16 iVersion;
        public Boolean fContainsSubDirectories;
        public Int32 iReserved;
    }
   

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C# 中调用 C++ DLL 中的 std::string 类型的方法,需要使用 `StringBuilder` 类来接收返回值,同时需要在 C# 中定义与 C++ 中的方法签名相匹配的委托类型,并使用 `Marshal.GetDelegateForFunctionPointer` 方法将 DLL 导出函数的指针转换为委托对象。以下是一个示例: C++ DLL 中的类和方法: ```cpp #include <string> class MyCppClass { public: std::string MyCppMethod(const std::string& str) { return "Hello " + str + " from C++!"; } }; extern "C" { __declspec(dllexport) MyCppClass* CreateMyCppClass() { return new MyCppClass(); } __declspec(dllexport) void DeleteMyCppClass(MyCppClass* p) { delete p; } __declspec(dllexport) void MyCppClass_MyCppMethod(MyCppClass* p, const char* str, char* buffer, int bufferSize) { std::string s(str); std::string result = p->MyCppMethod(s); strncpy(buffer, result.c_str(), bufferSize); } } ``` C# 代码: ```csharp using System; using System.Runtime.InteropServices; using System.Text; class Program { [DllImport("MyCppDll.dll")] public static extern IntPtr CreateMyCppClass(); [DllImport("MyCppDll.dll")] public static extern void DeleteMyCppClass(IntPtr p); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void MyCppClass_MyCppMethodDelegate(IntPtr p, string str, StringBuilder sb, int bufferSize); static void Main() { IntPtr p = CreateMyCppClass(); try { MyCppClass_MyCppMethodDelegate MyCppClass_MyCppMethod = (MyCppClass_MyCppMethodDelegate)Marshal.GetDelegateForFunctionPointer( Marshal.GetFunctionPointerForDelegate((MyCppClass_MyCppMethodDelegate)delegate { }), typeof(MyCppClass_MyCppMethodDelegate) ); StringBuilder sb = new StringBuilder(256); MyCppClass_MyCppMethod(p, "World", sb, sb.Capacity); Console.WriteLine(sb.ToString()); } finally { DeleteMyCppClass(p); } } } ``` 在上述代码中,我们首先声明了从 C++ DLL 中导入的函数 `CreateMyCppClass` 和 `DeleteMyCppClass`,它们分别用于创建和销毁 C++ 类的实例。接下来,我们定义了一个与 C++ 中的方法签名相匹配的委托类型 `MyCppClass_MyCppMethodDelegate`,并使用 `Marshal.GetDelegateForFunctionPointer` 方法将 DLL 导出函数 `MyCppClass_MyCppMethod` 的指针转换为委托对象。 在调用 C++ 类的方法之前,我们需要先创建一个 C++ 类的实例,并将其封装在 `IntPtr` 对象中。在调用 C++ 类的方法时,我们使用上述委托对象来调用 C++ DLL 中的函数 `MyCppClass_MyCppMethod`,并使用 `StringBuilder` 类来接收返回值。需要注意的是,在调用 `MyCppClass_MyCppMethod` 之前,我们需要先创建一个足够大的 `StringBuilder` 对象,并将其容量传递给 C++ DLL 中的方法,以确保能够接收到完整的字符串。最后,我们使用 `DeleteMyCppClass` 函数销毁 C++ 类的实例。 需要注意的是,在 C++ DLL 中,函数的参数类型必须为基本类型或指针类型,不能使用引用类型。另外,在 C++ DLL 中使用的字符串编码格式必须与 C# 中使用的字符串编码格式相同,否则可能会出现乱码问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值