`

C# 调用Dll中非托管C++代码时,函数参数的类型对照

阅读更多

在上一篇blog(工具(Tray Friend):将任何程序,最小化到系统托盘 )中。

使用C#调用了很多非托管的C++代码。

 

现在就把“C# 调用Dll中非托管C++代码时,函数参数的类型对照”这一问题做一个总结。

用这些关键字进行搜索,网上有不少这样那个的内容,比如下面这几个链接

 

C# 与 C++ 数据类型对照(后三篇内容一样)

http://topic.csdn.net/u/20090928/11/af7848c6-5071-41aa-92e2-e8d626d6aefe.html

 

http://blog.csdn.net/dz45693/archive/2009/09/26/4598867.aspx

http://www.cnblogs.com/yiki/archive/2008/10/29/1321848.html

http://blog.csdn.net/okadler0518/archive/2009/06/22/4289679.aspx

 

但是上面的映射有时候会出现问题。

比如上面的帖子都将LPTSTR映射成String,

然而在处理GetWindowText 函数是,因为这个LPTSTR是为了要将结果带回来的返回值。

因此在这里使用String便行不通了,而需要使用StringBuffer。

 

注:GetWindowText的原型

int GetWindowText(      
    HWND hWnd,
    LPTSTR lpString,
    int nMaxCount
);
 

 

如果问题的方法,仅仅是查看上面那几个链接,那么我一定不会写这篇博客。

我的主要目的是要介绍另外两种方法。

 

方法一:

查看Web版本的MSDN。

看看下面这两个连接,在Community Content部分都给出了C#,VB调用的原型。

当然,不是所有的函数对应的Community Content部分都有完整的事例。

但有的给出了一些常量的值,有的给出了一些结构体的定义,总之这部分内容还是具有参考价值。

注:安装在本机的MSDN没有Community Content这部分内容。

 

GetWindowText

http://msdn.microsoft.com/en-us/library/ms633520%28VS.85%29.aspx

 

GetForegroundWindow

http://msdn.microsoft.com/en-us/library/ms633505%28VS.85%29.aspx

 

 

方法二:

P/Invoke Interop Assistant

 

输入你想要的东西(Type,Constant,Procedure),他会自动生成相应的代码(C#,或VB)。

 

举例子说明。

当我要SHGetFileInfo调用这个函数是,需要用到类型:SHFileInfo

于是我在P/Invoke Interop Assistant查询类型SHFileInfo,便会得到下面结果:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Unicode)]
public struct SHFILEINFOW {
    
    /// HICON->HICON__*
    public System.IntPtr hIcon;
    
    /// int
    public int iIcon;
    
    /// DWORD->unsigned int
    public uint dwAttributes;
    
    /// WCHAR[260]
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=260)]
    public string szDisplayName;
    
    /// WCHAR[80]
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=80)]
    public string szTypeName;
}
 

 

再举一个例子。

对于前面提到的GetWindowText函数,如果在P/Invoke Interop Assistant的Procedure中进行查询的话。

也会得到下面的代码:

 

[System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetWindowText")]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
 

 

上面这段代码有经过我整理,自动生成的东西,可读性还是烧差一些,有冗余的东西。

尽管如此这一工具还是非常好用。

 

总结起来

配合这个工具,还有本文开头部分提到的C# 与 C++ 数据类型对照表。

分析分析,查找查找,是在不行再GoogleGoogle。

在C#中调用非托管dll代码,还是很方便的。

 

方便起见,我也将《C# 与 C++ 数据类型对照表》转载如下:

 

C++            C#
=====================================
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

 

 

API与C#的数据类型对应关系表
API数据类型 类型描述 C#类型 API数据类型 类型描述 C#类型
WORD 16位无符号整数 ushort CHAR 字符 char
LONG 32位无符号整数 int DWORDLONG 64位长整数 long
DWORD 32位无符号整数 uint HDC 设备描述表句柄 int
HANDLE 句柄,32位整数 int HGDIOBJ GDI对象句柄 int
UINT 32位无符号整数 uint HINSTANCE 实例句柄 int
BOOL 32位布尔型整数 bool HWM 窗口句柄 int
LPSTR 指向字符的32位指针 string HPARAM 32位消息参数 int
LPCSTR 指向常字符的32位指针 String LPARAM 32位消息参数 int
BYTE 字节 byte WPARAM 32位消息参数 int

 

 

BOOL=System.Int32
BOOLEAN=System.Int32
BYTE=System.UInt16
CHAR=System.Int16
COLORREF=System.UInt32
DWORD=System.UInt32
DWORD32=System.UInt32
DWORD64=System.UInt64
FLOAT=System.Float
HACCEL=System.IntPtr
HANDLE=System.IntPtr
HBITMAP=System.IntPtr
HBRUSH=System.IntPtr
HCONV=System.IntPtr
HCONVLIST=System.IntPtr
HCURSOR=System.IntPtr
HDC=System.IntPtr
HDDEDATA=System.IntPtr
HDESK=System.IntPtr
HDROP=System.IntPtr
HDWP=System.IntPtr
HENHMETAFILE=System.IntPtr
HFILE=System.IntPtr
HFONT=System.IntPtr
HGDIOBJ=System.IntPtr
HGLOBAL=System.IntPtr
HHOOK=System.IntPtr
HICON=System.IntPtr
HIMAGELIST=System.IntPtr
HIMC=System.IntPtr
HINSTANCE=System.IntPtr
HKEY=System.IntPtr
HLOCAL=System.IntPtr
HMENU=System.IntPtr
HMETAFILE=System.IntPtr
HMODULE=System.IntPtr
HMONITOR=System.IntPtr
HPALETTE=System.IntPtr
HPEN=System.IntPtr
HRGN=System.IntPtr
HRSRC=System.IntPtr
HSZ=System.IntPtr
HWINSTA=System.IntPtr
HWND=System.IntPtr
INT=System.Int32
INT32=System.Int32
INT64=System.Int64
LONG=System.Int32
LONG32=System.Int32
LONG64=System.Int64
LONGLONG=System.Int64
LPARAM=System.IntPtr
LPBOOL=System.Int16[]
LPBYTE=System.UInt16[]
LPCOLORREF=System.UInt32[]
LPCSTR=System.String
LPCTSTR=System.String
LPCVOID=System.UInt32
LPCWSTR=System.String
LPDWORD=System.UInt32[]
LPHANDLE=System.UInt32
LPINT=System.Int32[]
LPLONG=System.Int32[]
LPSTR=System.String
LPTSTR=System.String
LPVOID=System.UInt32
LPWORD=System.Int32[]
LPWSTR=System.String
LRESULT=System.IntPtr
PBOOL=System.Int16[]
PBOOLEAN=System.Int16[]
PBYTE=System.UInt16[]
PCHAR=System.Char[]
PCSTR=System.String
PCTSTR=System.String
PCWCH=System.UInt32
PCWSTR=System.UInt32
PDWORD=System.Int32[]
PFLOAT=System.Float[]
PHANDLE=System.UInt32
PHKEY=System.UInt32
PINT=System.Int32[]
PLCID=System.UInt32
PLONG=System.Int32[]
PLUID=System.UInt32
PSHORT=System.Int16[]
PSTR=System.String
PTBYTE=System.Char[]
PTCHAR=System.Char[]
PTSTR=System.String
PUCHAR=System.Char[]
PUINT=System.UInt32[]
PULONG=System.UInt32[]
PUSHORT=System.UInt16[]
PVOID=System.UInt32
PWCHAR=System.Char[]
PWORD=System.Int16[]
PWSTR=System.String
REGSAM=System.UInt32
SC_HANDLE=System.IntPtr
SC_LOCK=System.IntPtr
SHORT=System.Int16
SIZE_T=System.UInt32
SSIZE_=System.UInt32
TBYTE=System.Char
TCHAR=System.Char
UCHAR=System.Byte
UINT=System.UInt32
UINT32=System.UInt32
UINT64=System.UInt64
ULONG=System.UInt32
ULONG32=System.UInt32
ULONG64=System.UInt64
ULONGLONG=System.UInt64
USHORT=System.UInt16
WORD=System.UInt16
WPARAM=System.IntPtr

<---------补充----------->

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 位

 

 

 

 

 

分享到:
评论
3 楼 wjason 2012-01-18  
更多关于Managed, Native, and COM之间交互信息,
参考下面这个链接


Managed, Native, and COM Interop Team
http://clrinterop.codeplex.com/
2 楼 wjason 2009-10-30  
Microsoft Win32 to Microsoft .NET Framework API Map
http://msdn.microsoft.com/en-us/library/aa302340.aspx

这个链接也不错。
列出了已经映射成.net的api,他们与原api之间的对应关系。
1 楼 wjason 2009-10-30  
Visual Studio插件大搜索(60+)
http://www.pin5i.com/showtopic-15810.html

网上搜“visual studio 插件 60”
这篇文章有很多份。

里面第一个插件跟这个主题很靠谱
引用
A

    * Visual Studio Add-ins: API to .NET Mapping Maps common Win32API functions to their .NET CLR equivalents; and, allows the developer to search either MSDN online or Google for more information on either the Win32 function or its .NET counterpart.
    * Visual Studio Add-ins: Add Copyright Notice Allows the developer to specify a custom header that can be added to each code file


只是可惜连接已经无效了。

另外还有这个插件也很靠谱
引用
Visual Studio Add-ins: BE.pinvoke BE.pinvoke is the PINVOKE.NET Add-In for Visual Studio 2005. The UI looks very similar to original PINVOKE.NET Addin for Visual Studio 2003 (1.0), but it is totally new designed and it takes advantage from the new features of the .NET Framework 2.0. Have fun inserting PInvoke signatures into your Visual Studio Project.

相关推荐

    C#调用DLL中非托管C++函数参数类型对照

    C#调用DLL中非托管C++函数参数类型对照 在C#编程中,经常需要调用C++中的DLL类库,这就需要了解C++中的函数参数类型在C#中的对应关系。以下是基本数据类型的对照: * 一维数组:C#参数在基本类型前加ref或out,out...

    C# 调用C++DLL(函数参数包含指针)

    本篇文章将深入探讨如何在C#中调用一个C++DLL,特别是当DLL函数参数中包含指针时的处理方法。 首先,理解C#与C++之间的互操作性是关键。.NET框架提供了一个名为P/Invoke(Platform Invoke)的机制,允许C#代码调用...

    非托管C++调用C#的dll

    通常,C#调用C++编写的dll可以直接使用dllimport,但是C++调用C#编写的dll需要使用托管C++将C#的dll进行一次封装,然后由非托管C++调用封装好的dll。然而,CLR VIA C#提供了一种非托管C++直接调用的方法,该方法可以...

    c# 调用C++编写 的DLL函数各种参数传递问题。

    在 C# 调用 C++ 编写的 DLL 函数时,参数传递是一个非常重要的部分。这篇文章将详细介绍 C# 调用 C++ 编写的 DLL 函数各种参数传递问题,包括不返回值的参数、带返回值的参数、传递结构体指针和传递结构体数组等。 ...

    c#调用托管c++调用c++

    标题“c#调用托管c++调用c++”揭示了主要的技术路线:首先,C#代码会通过.NET Framework的托管环境调用C++的托管代码,然后,这部分托管C++代码会进一步调用非托管的C++ DLL。这种技术的应用场景广泛,例如,当需要...

    C#调用C++ DLL 托管

    在.NET框架中,C#能够通过托管代码与非托管代码(如C++编译的DLL)进行交互。这种技术使得开发者可以利用C++库的强大功能,同时享受C#的高级特性和开发效率。本篇文章将深入探讨如何在C#中使用托管方式调用C++ DLL,...

    C# Csharp 调用 C++的DLL中的回调函数

    在本例中,C++ DLL可能定义了一个接受回调函数作为参数的接口,这样在DLL内部执行到特定逻辑时,就可以通过这个回调函数通知C#代码。 接下来,让我们转向C#(Csharp)部分。C#不能直接调用C++的函数,但可以通过...

    C#调用c++函数的dll文件,同时实现c++调用c#函数

    3. **C++调用托管方法**:在C++代码中,通过实例化`ManagedBridge`对象并调用其成员函数,就可以调用到C#的方法。C++/CLI会处理底层的类型转换和调用过程。 4. **C#实现回调函数**:在C#中,我们需要提供一个符合...

    C#使用CLR调用C++的DLL库

    然后,创建托管C++类,这些类封装了C++ DLL中的非托管代码,并提供给C#应用程序调用的接口。 3. **创建C# EXE应用** - 最后,创建一个C#控制台应用程序项目。在C#代码中,添加对C++ CLR类库的引用。然后,你可以像...

    C#动态调用DLL并对目标函数传递参数

    在.NET框架中,C#语言提供了强大的类型安全和编译时检查,但有时我们需要在运行时动态地加载和调用DLL中的函数,这种情况通常涉及到“反射”这一核心特性。本篇将深入探讨如何使用C#进行动态DLL调用以及如何向目标...

    C#调用C++动态DLL

    P/Invoke允许C#代码调用非托管代码,如C++的函数。以下是调用C++动态DLL的步骤: 1. **定义C++接口**:首先,你需要知道C++ DLL中的函数签名。C++函数在C#中调用时,必须遵循C的调用约定,这意味着函数应为“extern...

    C# 调用c++ 库 参数为指针类型导出函数

    c# Csharp调用 c++库 参数为导入和导出指针两种 包含C++ DLL源码 如fun(cont char* A,char*B) A为输入参数,B为输出参数-C# CSharp call C++ DLL lib dll function param use export and import eg: fun(cont char*...

    C#调用C++DLL动态库.rar_C#调用C++DLL动态库_c++dll动态库_c++开发动态库

    C#调用C++ DLL时可能会遇到异常,例如找不到DLL或函数,或者参数不匹配。因此,需要适当的错误处理机制,例如使用`try-catch`块。 7. **平台兼容性**: 跨平台开发时,需要注意C++ DLL是否适用于目标平台(如x86...

    c#调用c++DLL,dll有二维数组

    标题中的“c#调用c++DLL,dll有二维数组”意味着我们将在C++的DLL中定义一个二维数组,然后在C#中调用该函数并处理这个数组。在C++中,二维数组通常以指针的形式传递,因为C++不支持引用参数。而在C#中,我们通常...

    c#调用c++ dll 传参 string 崩溃的一种解决办法

    然而,当C#应用程序尝试调用C++ DLL中的函数并传递字符串参数时,可能会遇到一些挑战。 #### 字符串处理差异 问题的核心在于C#与C++对字符串的不同处理方式。在C#中,字符串是不可变的对象,类型为`System.String`...

    C#调用C++DLL导出类

    在.NET环境中,C#代码通常与C++代码交互是通过平台调用(P/Invoke)或托管C++来实现的。然而,当涉及到C++动态链接库(DLL)中的类时,情况会变得稍微复杂一些。本文将详细介绍如何在C#中调用C++DLL中的类,以及如何...

    C#DLL调用.rar_C# 调用 C++的DLL_C# 调用DLL库_c# 调用dll_c#调用C++dll_c#调用dll

    在.NET框架中,C#是一种常用的编程语言,它允许开发者调用非托管代码,例如C++编译的DLL库。这种技术使得C#程序能够利用已有的C++库,提高开发效率并重用代码资源。本文将深入探讨如何在C#中调用C++的DLL库,以及...

    C#调用C++DLL实例代码

    总结来说,C#调用C++DLL涉及到P/Invoke技术,需要定义正确的函数签名,使用`DllImport`属性,处理异常,以及正确地转换数据类型。通过熟练掌握这些技巧,开发者可以充分利用现有的C++库,同时享受C#带来的开发便利性...

    C#调用CDLL带指针参数的函数

    C#中调用DLL,尤其是C或C++编译的DLL时,可能会涉及到指针参数,这是由于C#与C/C++在内存管理上的差异。本篇将详细讲解如何在C#中调用CDLL,并处理带指针参数的函数。 首先,了解C#与C/C++的区别。C#是一种托管语言...

Global site tag (gtag.js) - Google Analytics