选择显示字体大小

c# 程序员参考--平台调用教程

平台调用服务 (pinvoke) 允许托管代码调用在 dll 中实现的非托管函数。

本教程说明使用什么方法才能从 c# 调用非托管 dll 函数。该教程所讨论的属性允许您调用这些函数并使数据类型得到正确封送。

教程

c# 代码有以下两种可以直接调用非托管代码的方法:

对于这两种技术,都必须向 c# 编译器提供非托管函数的声明,并且还可能需要向 c# 编译器提供如何封送与非托管代码之间传递的参数和返回值的说明。

该教程由下列主题组成:

该教程包括下列示例:

直接从 c# 调用 dll 导出

若要声明一个方法使其具有来自 dll 导出的实现,请执行下列操作:

示例 1

本示例显示如何使用 dllimport 属性通过调用 msvcrt.dll 中的 puts 输出消息。

// pinvoketest.csusing system;using system.runtime.interopservices;class platforminvoketest{    [dllimport("msvcrt.dll")]    public static extern int puts(string c);    [dllimport("msvcrt.dll")]    internal static extern int _flushall();    public static void main()     {        puts("test");        _flushall();    }}

输出

test

代码讨论

前面的示例显示了声明在非托管 dll 中实现的 c# 方法的最低要求。platforminvoketest.puts 方法用 static 和 extern 修饰符声明并且具有 dllimport 属性,该属性使用默认名称 puts 通知编译器此实现来自 msvcrt.dll。若要对 c# 方法使用不同的名称(如 putstring),则必须在 dllimport 属性中使用 entrypoint 选项,如下所示:

[dllimport("msvcrt.dll", entrypoint="puts")]

有关 dllimport 属性的语法的更多信息,请参见 dllimportattribute 类。

默认封送处理和为非托管方法的参数指定自定义封送处理

当从 c# 代码中调用非托管函数时,公共语言运行库必须封送参数和返回值。

对于每个 .net framework 类型均有一个默认非托管类型,公共语言运行库将使用此非托管类型在托管到非托管的函数调用中封送数据。例如,c# 字符串值的默认封送处理是封送为 lptstr(指向 tchar 字符缓冲区的指针)类型。可以在非托管函数的 c# 声明中使用 marshalas 属性重写默认封送处理。

示例 2

本示例使用 dllimport 属性输出一个字符串。它还显示如何通过使用 marshalas 属性重写函数参数的默认封送处理。

// marshal.csusing system;using system.runtime.interopservices;class platforminvoketest{    [dllimport("msvcrt.dll")]    public static extern int puts(        [marshalas(unmanagedtype.lpstr)]        string m);    [dllimport("msvcrt.dll")]    internal static extern int _flushall();    public static void main()     {        puts("hello world!");        _flushall();    }}

输出

运行此示例时,字符串

hello world!

将显示在控制台上。

代码讨论

在前面的示例中,puts 函数的参数的默认封送处理已从默认值 lptstr 重写为 lpstr。

marshalas 属性可以放置在方法参数、方法返回值以及结构和类的字段上。若要设置方法返回值的封送处理,请将 marshalas 属性与返回属性位置重写一起放置在方法上的属性块中。例如,若要显式设置 puts 方法返回值的封送处理:

...[dllimport("msvcrt.dll")] [return : marshalas(unmanagedtype.i4)]public static extern int puts( ...

有关 marshalas 属性的语法的更多信息,请参见 marshalasattribute 类。

注意   in 和 out 属性可用于批注非托管方法的参数。它们与 midl 源文件中的 in 和 out 修饰符的工作方式类似。请注意,out 属性与 c# 参数修饰符 out 不同。有关 in 和 out 属性的更多信息,请参见 inattribute 类和 outattribute 类。

为用户定义的结构指定自定义封送处理

可以为传递到非托管函数或从非托管函数返回的结构和类的字段指定自定义封送处理属性。通过向结构或类的字段中添加 marshalas 属性可以做到这一点。还必须使用 structlayout 属性设置结构的布局,还可以控制字符串成员的默认封送处理,并设置默认封装大小。

示例 3

本示例说明如何为结构指定自定义封送处理属性。

请考虑下面的 c 结构:

typedef struct taglogfont {    long lfheight;    long lfwidth;    long lfescapement;    long lforientation;    long lfweight;    byte lfitalic;    byte lfunderline;    byte lfstrikeout;    byte lfcharset;    byte lfoutprecision;    byte lfclipprecision;    byte lfquality;    byte lfpitchandfamily;    tchar lffacename[lf_facesize]; } logfont; 

c# 中,可以使用 structlayout 和 marshalas 属性描述前面的结构,如下所示:

// logfont.cs// compile with: /target:moduleusing system;using system.runtime.interopservices;[structlayout(layoutkind.sequential)]public class logfont {     public const int lf_facesize = 32;    public int lfheight;     public int lfwidth;     public int lfescapement;     public int lforientation;     public int lfweight;     public byte lfitalic;     public byte lfunderline;     public byte lfstrikeout;     public byte lfcharset;     public byte lfoutprecision;     public byte lfclipprecision;     public byte lfquality;     public byte lfpitchandfamily;    [marshalas(unmanagedtype.byvaltstr, sizeconst=lf_facesize)]    public string lffacename; }

有关 structlayout 属性的语法的更多信息,请参见 structlayoutattribute 类。

然后即可将该结构用在 c# 代码中,如下所示:

// pinvoke.cs// compile with: /addmodule:logfont.netmoduleusing system;using system.runtime.interopservices; class platforminvoketest{         [dllimport("gdi32.dll", charset=charset.auto)]      public static extern intptr createfontindirect(            [in, marshalas(unmanagedtype.lpstruct)]            logfont lplf   // characteristics            );       [dllimport("gdi32.dll")]      public static extern bool deleteobject(            intptr handle            );       public static void main()       {            logfont lf = new logfont();            lf.lfheight = 9;            lf.lffacename = "arial";            intptr handle = createfontindirect(lf);             if (intptr.zero == handle)            {                  console.writeline("can't creates a logical font.");            }            else            {                                    if (intptr.size == 4)                        console.writeline("{0:x}", handle.toint32());                  else                        console.writeline("{0:x}", handle.toint64());                           // delete the logical font created.                  if (!deleteobject(handle))                       console.writeline("can't delete the logical font");            }      }}

运行示例

c30a0ae5

代码讨论

在前面的示例中,createfontindirect 方法使用了一个 logfont 类型的参数。marshalas 和 in 属性用于限定此参数。程序将由此方法返回的数值显示为十六进制大写字符串。

注册回调方法

若要注册调用非托管函数的托管回调,请用相同的参数列表声明一个委托并通过 pinvoke 传递它的一个实例。在非托管端,它将显示为一个函数指针。有关 pinvoke 和回调的更多信息,请参见平台调用详解。

例如,考虑以下非托管函数 myfunction,此函数要求 callback 作为其参数之一:

typedef void (__stdcall *pfn_mycallback)();int __stdcall myfunction(pfn_ mycallback callback);

若要从托管代码调用 myfunction,请声明该委托,将 dllimport 附加到函数声明,并根据需要封送任何参数或返回值:

public delegate void mycallback();[dllimport("mydll.dll")]public static extern void myfunction(mycallback callback);

同时,请确保委托实例的生存期覆盖非托管代码的生存期;否则,委托在经过垃圾回收后将不再可用。


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons