没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
使用 C#调用 windows API 入门(一)
一:入门,直接从 C# 调用 DLL 导出
其实我们的议题应该叫做 如何直接调用非托管代码,通常有 种方法:
. 直接调用从 导出的函数。
. 调用 对象上的接口方法
我主要讨论从 中导出函数,基本步骤如下:
.使用 关键字 static和 extern声明方法。
.将 DllImport属性附加到该方法。DllImport属性允许您指定包含该方法的 的名
称。
.如果需要,为方法的参数和返回值指定自定义封送处理信息,这将重写
的默认封送处理。
好,我们开始
.首先我们查询 找到 的定义
GetShortPathName !" "#$$%$%!"&
%
DWORDGetShortPathName(
LPCTSTRlpszLongPath,
LPTSTRlpszShortPath,
DWORDcchBuer
);
.查找对照表进行数据类型的转换(出处:%'(($ "!$!($ )("$$$(
*(*+(($%,-&). )/%$
Win32 Types Speci'cation CLR Type
!0120340
56789:
2;<"$")
" )
/$3/
$0$" 01=0
57
=;<"$")
" )
/$1 =
" 0 )0 )" 0
100
389:01
;<"$")
" )
/$1
>>" =?01=?0
=?;<"$")
" )
/$1 =?
Win32 Types Speci'cation CLR Type
$") !0@120
@56789:034
2;<" $")
" )
/$3/
$") $0
@1=0@570
A7060
A56789:0>>!>
=;<" $")
" )
/$@1 =
$") 0 $")
" 0@10@0
A70@0
A70@1
;<" $")
" )
/$@1
$") >>" =?0
@1=?0
A70
@
=?;<" $")
" )
/$@1 =?
B06 " );%!"$"
B" )%"
/$" )
<0 )<0
@3
<;%!"$"
B" )%"
/$<
89:1 A" "$/%"$ " )"$%!"/
$$") " )C" ! $07%#"$$%!"&!
/%#"$ " )
.调用 这个 61,简单的写法如下(编译通过的话),
$" )/$C
$" )System.Runtime.InteropServices;
%<"!!$$D>#5
E
FDllImportGH HIJ
%<"!static extern"
G
$" )%0
" )3"$0
" $ )
I
K
而我们之前的例子:
$" )/$C
$" )/$7 "1 %#"!$C
%<"!!$$D>#5
E
F1%GH H0.6IJ
%<"!$"!, "
G
F$6$G@ )/%IJ$" )%0
F$6$G@ )/%IJ" )3"$0
" $ )
I
K
对比可知,其中 1%,$"!,, 基本上是必须有的,其他
,$6$(…)是可选项,在这里即使没有,程序也是可以调用此 61 了。
说明:
.D>#5 方法用 static和 extern修饰符声明并
且具有 DllImport属性,该属性使用默认名称 通知编译器此实现来自
。若要对 方法使用不同的名称(如 )),则必须在 DllImport属性
中使用 EntryPoint选项,如下所示:
[DllImport("kernel32.dll", EntryPoint="getShort")]
2.使用 $6$G@ )/%I保证了在任何平台上都会得到 ,否则
默认的方式会把从 中的字符串作为 3 传递。
现在如果是仅含有简单参数和返回值的 A161,就都可以利用这种方法进行对照,简单的
改写和调用了。
二.背后的原理 ―― 知其所以然,相关的知识
1.平台调用详原理
平台调用依赖于元数据在运行时查找导出的函数并封送其参数。下图显示了这一过程。
对非托管 函数的“平台调用”调用
当“平台调用”调用非托管函数时,它将依次执行以下操作:
查找包含该函数的 。
将该 加载到内存中。
查找函数在内存中的地址并将其参数推到堆栈上,以封送所需的数据。
注意 只在第一次调用函数时,才会查找和加载 并查找函数在内存中的地址。
将控制权转移给非托管函数。
平台调用会向托管调用方引发由非托管函数生成的异常。
2.关于 Attribute(属性,注意蓝色字)
属性可以放置在几乎所有声明中(但特定的属性可能限制它在其上有效的声明类型)。在语法
上,属性的指定方法为:将括在方括号中的属性名置于其适用的实体声明之前。例如,具有
DllImport属性的类将声明如下:
F1%J%<"!!$$/"%$$EK
有关更多信息,请参见 1%6"<类。
许多属性都带参数,而这些参数可以是定位(未命名)参数也可以是命名参数。任何定位参数
都必须按特定顺序指定并且不能省略,而命名参数是可选的且可以按任意顺序指定。首先指定
定位参数。例如,这三个属性是等效的:
F1%GH$H0$.$0,!%" ).$IJ
F1%GH$H0,!%" ).$0$.$IJ
F1%GH$HIJ
第一个参数(名称)是定位参数并且总是第一个出现,其他参数为命名参数。在此例中,
两个命名参数都默认为假,因此它们可以省略(有关默认参数值的信息,请参见各个属性的文
档)。
在一个声明中可以放置多个属性,可分开放置,也可放在同一组括号中:
<6GF1 JFJ<,IC
<6GFJF1 J<,IC
<6GF1 0J<,IC
某些属性对于给定实体可以指定多次。此类可多次使用的属性的一个示例是 "" :
F "" GH3@HI0 "" GHHIJ#"!GIEK
注意 根据约定,所有属性名称都以单词“6"<L结束,以便将它们与
中的其他项区分。但是,在代码中使用属性时不需要指定属性后缀。例如,F1%J虽等
效于 F1%6"<J,但 DllImportAttribute才是该属性在 中
的实际名称。
3.MarshalAsAttribute 类
指示如何在托管代码和非托管代码之间封送数据。可将该属性应用于参数、字段或返回值。
该属性为可选属性,因为每个数据类型都有默认的封送处理行为。
大多数情况下,该属性只是使用 @ )/%枚举标识非托管数据的格式。
例如,默认情况下,公共语言运行库将字符串参数作为 BStr封送到 方法,但是可以通
过制定 $6$ 属性,将字符串作为 、A、或 3封送到非托管代码。
某些 UnmanagedType枚举成员需要附加信息。
三:进阶,如何处理含有复杂的参数和返回值类型的 61 的调用(3 " M)
暴强贴:从.NET 平台调用 Win32 API
小序
:::::::A" 61 可以直接控制 "!$A" $ 的核心,因为
61(6%%"!" )" )1 !)本来就是微软留给我们直接控
制 A" $ 的接口。想玩儿吗?呵呵,太难了。
:::::::使用非常简单,写程序就像打拱猪,/:;>;N,搭积木一样简单。
想玩儿吗?呵呵,没办法直接控制 A" $ 的核心。
::::::::难道就没有两全其美的办法吗?当然不是!要不微软的产品早就没人买了。
其实从 (或者说 平台)调用 A" 61 还是非常简单滴OOOO今天
偶们大家就一起来研究研究。
一. 基础知识
:::::::A" 61 是 语言(注意,不是 PP语言,尽管 语言是 PP语言
的子集)函数集。C#语言与 C 语言是完全不同的(除了语法上比较像),所
以,要想用 语言调用 语言的 A" 61,要费上一番周折。首先我们就
要准备一些基础知识。
A" 61 函数放在哪里?
:::::::A" 61 函数是 A" $ 的核心,比如我们看到的窗体、按钮、对
话框什么的,都是依靠 A" 函数“画”在屏幕上的,由于这些控件(有时也称
组件)都用于用户与 A" $ 进行交互,所以控制这些控件的 A" 61 函
数称为“用户界面”函数(@$1 !A" 61),简称 @1 函数;还有一
些函数,并不用于交互,比如管理当前系统正在运行的进程、硬件系统状态的
监视等等……这些函数只有一套,但是可以被所有的 A" $ 程序调用(只
要这个程序的权限足够高),简而言之,61 是为程序所共享的。为了达到所
有程序能共享一套 61 的目的,A" $ 采用了“动态链接库”的办法。之所以
叫“动态链接库”,是因为这样的函数库的调用方式是“随用随取”而不是像静态链
接库那样“用不用都要带上”。
:::::::这里不太好理解,不要紧,我们举个小例子。我们把 A" $ 比做一个
游乐场,而把在游乐场里玩儿的小孩比做一个一个程序。小孩在玩的过程中可
能要喝水。我们有两个办法让小家伙们想喝水的时候就有水喝:给每个小家
伙配一个水壶,小家伙们喝了的话就喝自己带的水;给游乐场配一个饮水机,
谁渴了谁来喝。显然,第二个方法要好得多,这体现在三个地方。第一,带着
水壶,小家伙身体不灵活、玩不爽(影响程序的速度),况且这只是带了一个
水壶,要是再带上饭盒呢?还有轮滑、头盔、创可贴、纱布……6Q;?+/
,如果带全了就赶上美国大兵了。所以游乐园里还是有个公用“仓库”要来
的方便,让大家随用随取(动态链接)。第二,小家伙们带了那么多东西,占
剩余63页未读,继续阅读
资源评论
- Cs52312013-04-16嗯,介绍很详细
yongping8204
- 粉丝: 57
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功