- 浏览: 896146 次
- 性别:
- 来自: 大连
文章分类
- 全部博客 (319)
- Thinking / 反思 (27)
- 我读的技术类图书 (3)
- 我读的非技术图书 (3)
- Java & Groovy (55)
- Ruby/Rails (9)
- Python (10)
- C/C++ (14)
- C# & .net (9)
- 互联网相关技术 (6)
- Database (6)
- Unix/Linux (6)
- WindowsDev (21)
- 工具使用 / Tips (62)
- 编程技术杂谈/咨讯 (6)
- 软工 / 敏捷 / 模式 (6)
- 易筋经 / 各种内功 (3)
- 充电 / 他学科知识 (6)
- 外语学习 (16)
- 我和宝宝的甜蜜生活 (24)
- 八卦 (3)
- 健康 (0)
- 无类别 (0)
- mTogether (4)
- 一页纸 (3)
- SAP (7)
- baby (2)
- abap (2)
- temp (1)
- network (1)
- 生活 (1)
最新评论
-
daliang1215:
收藏一下,好东西。 xp 的快捷键用的非常爽,到win7缺没有 ...
Windows7: 右键任务栏上的一个窗口, 用快捷键c关闭它 -
Alice南京:
感谢
Java GC 监视方法与工具 -
wjason:
今天在excel 2010上面写了一些代码,果然lookup有 ...
Excel 公式: 根据一个单元格的用户输入值, 自动设置另一个单元格的值 -
wjason:
因式分解:http://zh.wikipedia.org/wi ...
教孩子学编程: 数学题1 -
bbls:
不错 找了好久了
VS2010: 在Solution Explorer中,自动关联当前正在编辑的文件
在上一篇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
方法二:
输入你想要的东西(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 位
评论
参考下面这个链接
Managed, Native, and COM Interop Team
http://clrinterop.codeplex.com/
http://msdn.microsoft.com/en-us/library/aa302340.aspx
这个链接也不错。
列出了已经映射成.net的api,他们与原api之间的对应关系。
http://www.pin5i.com/showtopic-15810.html
网上搜“visual studio 插件 60”
这篇文章有很多份。
里面第一个插件跟这个主题很靠谱
* 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
只是可惜连接已经无效了。
另外还有这个插件也很靠谱
发表评论
-
C# in depth要点整理(一张A4纸, 打印版)
2013-03-23 14:42 2811需要学习的东西越来越多, 需要记住的东西也回来越多. 所 ... -
WPF: 定制datagrid, 让他更漂亮些 & WPF其他资料整理
2013-02-01 16:16 11346前些日子, 我们准备, 为我们的打印机解决方案中增加一个新 ... -
C# : 操作Word文件的API - (将C# source中的xml注释转换成word文档)
2012-06-25 14:56 4659这篇博客将要讨论的是 ... -
C# API: 生成和读取Excel文件
2012-06-20 17:24 8632们想为用户提供一些数据,考虑再三, 大家认为对于用户(人,而非 ... -
使用C#: 自动切换鼠标的左右手习惯
2009-08-03 15:22 3208不知道我得的是鼠标手,还是肩周炎。 长时间右手(或者左手)使 ... -
使用C#控制系统音量
2009-05-08 13:49 2953两个方法. 方法一: 1. 导入API定义 ... -
使用C#注册全局快捷键
2009-05-07 14:13 2921天试了一下这个, 记录下来, 以后我给自己做小工具时, 肯定用 ... -
C#中调用外部exe - 书C# for java developer的使用
2008-06-30 11:18 2768《C# for java developer》是本好书,里面对 ...
相关推荐
C#调用DLL中非托管C++函数参数类型对照 在C#编程中,经常需要调用C++中的DLL类库,这就需要了解C++中的函数参数类型在C#中的对应关系。以下是基本数据类型的对照: * 一维数组:C#参数在基本类型前加ref或out,out...
本篇文章将深入探讨如何在C#中调用一个C++DLL,特别是当DLL函数参数中包含指针时的处理方法。 首先,理解C#与C++之间的互操作性是关键。.NET框架提供了一个名为P/Invoke(Platform Invoke)的机制,允许C#代码调用...
通常,C#调用C++编写的dll可以直接使用dllimport,但是C++调用C#编写的dll需要使用托管C++将C#的dll进行一次封装,然后由非托管C++调用封装好的dll。然而,CLR VIA C#提供了一种非托管C++直接调用的方法,该方法可以...
在 C# 调用 C++ 编写的 DLL 函数时,参数传递是一个非常重要的部分。这篇文章将详细介绍 C# 调用 C++ 编写的 DLL 函数各种参数传递问题,包括不返回值的参数、带返回值的参数、传递结构体指针和传递结构体数组等。 ...
标题“c#调用托管c++调用c++”揭示了主要的技术路线:首先,C#代码会通过.NET Framework的托管环境调用C++的托管代码,然后,这部分托管C++代码会进一步调用非托管的C++ DLL。这种技术的应用场景广泛,例如,当需要...
在.NET框架中,C#能够通过托管代码与非托管代码(如C++编译的DLL)进行交互。这种技术使得开发者可以利用C++库的强大功能,同时享受C#的高级特性和开发效率。本篇文章将深入探讨如何在C#中使用托管方式调用C++ DLL,...
在本例中,C++ DLL可能定义了一个接受回调函数作为参数的接口,这样在DLL内部执行到特定逻辑时,就可以通过这个回调函数通知C#代码。 接下来,让我们转向C#(Csharp)部分。C#不能直接调用C++的函数,但可以通过...
3. **C++调用托管方法**:在C++代码中,通过实例化`ManagedBridge`对象并调用其成员函数,就可以调用到C#的方法。C++/CLI会处理底层的类型转换和调用过程。 4. **C#实现回调函数**:在C#中,我们需要提供一个符合...
C++/CLI提供了一种桥梁,让传统的C++代码能够访问托管代码(如C#的DLL)。 调用步骤如下: 1. 创建C# DLL:在C#项目中定义一个公共类,包含需要调用的方法。例如,可以有一个名为`Calculator`的类,其中有一个`Add...
然后,创建托管C++类,这些类封装了C++ DLL中的非托管代码,并提供给C#应用程序调用的接口。 3. **创建C# EXE应用** - 最后,创建一个C#控制台应用程序项目。在C#代码中,添加对C++ CLR类库的引用。然后,你可以像...
在.NET框架中,C#语言提供了强大的类型安全和编译时检查,但有时我们需要在运行时动态地加载和调用DLL中的函数,这种情况通常涉及到“反射”这一核心特性。本篇将深入探讨如何使用C#进行动态DLL调用以及如何向目标...
P/Invoke允许C#代码调用非托管代码,如C++的函数。以下是调用C++动态DLL的步骤: 1. **定义C++接口**:首先,你需要知道C++ DLL中的函数签名。C++函数在C#中调用时,必须遵循C的调用约定,这意味着函数应为“extern...
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时可能会遇到异常,例如找不到DLL或函数,或者参数不匹配。因此,需要适当的错误处理机制,例如使用`try-catch`块。 7. **平台兼容性**: 跨平台开发时,需要注意C++ DLL是否适用于目标平台(如x86...
然而,当C#应用程序尝试调用C++ DLL中的函数并传递字符串参数时,可能会遇到一些挑战。 #### 字符串处理差异 问题的核心在于C#与C++对字符串的不同处理方式。在C#中,字符串是不可变的对象,类型为`System.String`...
标题中的“c#调用c++DLL,dll有二维数组”意味着我们将在C++的DLL中定义一个二维数组,然后在C#中调用该函数并处理这个数组。在C++中,二维数组通常以指针的形式传递,因为C++不支持引用参数。而在C#中,我们通常...
在.NET环境中,C#代码通常与C++代码交互是通过平台调用(P/Invoke)或托管C++来实现的。然而,当涉及到C++动态链接库(DLL)中的类时,情况会变得稍微复杂一些。本文将详细介绍如何在C#中调用C++DLL中的类,以及如何...
在.NET框架中,C#是一种常用的编程语言,它允许开发者调用非托管代码,例如C++编译的DLL库。这种技术使得C#程序能够利用已有的C++库,提高开发效率并重用代码资源。本文将深入探讨如何在C#中调用C++的DLL库,以及...
总结来说,C#调用C++DLL涉及到P/Invoke技术,需要定义正确的函数签名,使用`DllImport`属性,处理异常,以及正确地转换数据类型。通过熟练掌握这些技巧,开发者可以充分利用现有的C++库,同时享受C#带来的开发便利性...