请问C#高手:[DllImport(kernel32.dll)]是什么意思??请问C#高手:[DllImport(kernel32.dll)]是什么意思??这叫引入kernel32.dll这个动态连接库。这个动态连接库里面包含了很多WindowsAPI函数,如果你想使用这面的函数,就需要这么引入。举个例子:[DllImport(kernel32.dll)]privatestaticexternvoid函数名(参数,[参数]);函数名就是一个属于kernel32.dll里的一个函数。完了你就可以用那个函数了。kernel32.dll调用kernel32.dll这个DLL里面的API接口!系统API例如[DllImport(user32.dll)]//--引入APIpublicstaticexternReturnTypeFunctionName(typearg1,typearg2,...);//--声明方法调用该方法是和调用普通方法没区别DLLImport属性现在是更深入地进行探讨的时候了。在对托管代码进行P/Invoke调用时,DllImportAttribute类型扮演着重要的角色。DllImportAttribute的主要作用是给CLR指示哪个DLL导出您想要调用的函数。相关DLL的名称被作为一个构造函数参数传递给DllImportAttribute。如果您无法肯定哪个DLL定义了您要使用的WindowsAPI函数,PlatformSDK文档将为您提供最好的帮助资源。在WindowsAPI函数主题文字临近结尾的位置,SDK文档指定了C应用程序要使用该函数必须链接的.lib文件。在几乎所有的情况下,该.lib文件具有与定义该函数的系统DLL文件相同的名称。例如,如果该函数需要C应用程序链接到Kernel32.lib,则该函数就定义在Kernel32.dll中。您可以在MessageBeep中找到有关MessageBeep的PlatformSDK文档主题。在该主题结尾处,您会注意到它指出库文件是User32.lib;这表明MessageBeep是从User32.dll中导出的。可选的DllImportAttribute属性除了指出宿主DLL外,DllImportAttribute还包含了一些可选属性,其中四个特别有趣:EntryPoint、CharSet、SetLastError和CallingConvention。EntryPoint在不希望外部托管方法具有与DLL导出相同的名称的情况下,可以设置该属性来指示导出的DLL函数的入口点名称。当您定义两个调用相同非托管函数的外部方法时,这特别有用。另外,在Windows中还可以通过它们的序号值绑定到导出的DLL函数。如果您需要这样做,则诸如“#1”或“#129”的EntryPoint值指示DLL中非托管函数的序号值而不是函数名。CharSet对于字符集,并非所有版本的Windows都是同样创建的。Windows9x系列产品缺少重要的Unicode支持,而WindowsNT和WindowsCE系列则一开始就使用Unicode。在这些操作系统上运行的CLR将Unicode用于String和Char数据的内部表示。但也不必担心—当调用Windows9xAPI函数时,CLR会自动进行必要的转换,将其从Unicode转换为ANSI。如果DLL函数不以任何方式处理文本,则可以忽略DllImportAttribute的CharSet属性。然而,当Char或String数据是等式的一部分时,应该将CharSet属性设置为CharSet.Auto。这样可以使CLR根据宿主OS使用适当的字符集。如果没有显式地设置CharSet属性,则其默认值为CharSet.Ansi。这个默认值是有缺点的,因为对于在Windows2000、WindowsXP和WindowsNT®上进行的interop调用,它会消极地影响文本参数封送处理的性能。应该显式地选择CharSet.Ansi或CharSet.Unicode的CharSet值而不是使用CharSet.Auto的唯一情况是:您显式地指定了一个导出函数,而该函数特定于这两种Win32OS中的某一种。ReadDirectoryChangesWAPI函数就是这样的一个例子,它只存在于基于WindowsNT的操作系统中,并且只支持Unicode;在这种情况下,您应该显式地使用CharSet.Unicode。有时,WindowsAPI是否有字符集关系并不明显。一种决不会有错的确认方法是在PlatformSDK中检查该函数的C语言头文件。(如果您无法肯定要看哪个头文件,则可以查看PlatformSDK文档中列出的每个API函数的头文件。)如果您发现该API函数确实定义为一个映射到以A或W结尾的函数名的宏,则字符集与您尝试调用的函数有关系。WindowsAPI函数的一个例子是在WinUser.h中声明的GetMessageAPI,您也许会惊讶地发现它有A和W两种版本。SetLastError错误处理非常重要,但在编程时经常被遗忘。当您进行P/Invoke调用时,也会面临其他的挑战—处理托管代码中WindowsAPI错误处理和异常之间的区别。我可以给您一点建议。如果您正在使用P/Invoke调用WindowsAPI函数,而对于该函数,您使用GetLastError来查找扩展的错误信息,则应该在外部方法的DllImportAttribute中将SetLastError属性设置为true。这适用于大多数外部方法。这会导致CLR在每次调用外部方法之后缓存由API函数设置的错误。然后,在包装方法中,可以通过调用类库的System.Runtime.InteropServices.Marshal类型中定义的Marshal.GetLastWin32Error方法来获取缓存的错误值。我的建议是检查这些期望来自API函数的错误值,并为这些值引发一个可感知的异常。对于其他所有失败情况(包括根本就没意料到的失败情况),则引发在System.ComponentModel命名空间中定义的Win32Exception,并将Marshal.GetLastWin32Error返回的值传递给它。如果您回头看一下图1中的代码,您会看到我在externMessageBeep方法的公共包装中就采用了这种方法。CallingConvention我将在此介绍的最后也可能是最不重要的一个DllImportAttribute属性是CallingConvention。通过此属性,可以给CLR指示应该将哪种函数调用约定用于堆栈中的参数。CallingConvention.Winapi的默认值是最好的选择,它在大多数情况下都可行。然而,如果该调用不起作用,则可以检查PlatformSDK中的声明头文件,看看您调用的API函数是否是一个不符合调用约定标准的异常API。通常,本机函数(例如WindowsAPI函数或C-运行时DLL函数)的调用约定描述了如何将参数推入线程堆栈或从线程堆栈中清除。大多数WindowsAPI函数都是首先将函数的最后一个参数推入堆栈,然后由被调用的函数负责清理该堆栈。相反,许多C-运行时DLL函数都被定义为按照方法参数在方法签名中出现的顺序将其推入堆栈,将堆栈清理工作交给调用者。幸运的是,要让P/Invoke调用工作只需要让外围设备理解调用约定即可。通常,从默认值CallingConvention.Winapi开始是最好的选择。然后,在C运行时DLL函数和少数函数中,可能需要将约定更改为CallingConvention.Cdecl。C#API大全作者:不详加入时间:4/17/20089:41:49AMC#APIC:\ProgramFiles\MicrosoftVisualStudio.NET\FrameworkSDK\Samples\Technologies\Interop\PlatformInvoke\WinAPIs\CS目录下有大量的调用API的例子。一、调用格式usingSystem.Runtime.InteropServices;//引用此名称空间,简化后面的代码//使用DllImportAttribute特性来引入api函数,注意声明的是空方法,即方法体为空。[DllImport(user32.dll)]publicstaticexternReturnTypeFunctionName(typearg1,typearg2,...);//调用时与调用其他方法并无区别可以使用字段进一步说明特性,用逗号隔开,如:[DllImport(kernel32,EntryPoint=GetVersionEx)]DllImportAttribute特性的公共字段如下:1、CallingConvention指示向非托管实现传递方法参数时所用的CallingConvention值。CallingConvention.Cdecl:调用方清理堆栈。它使您能够调用具有varargs的函数。CallingConvention.StdCall:被调用方清理堆栈。它是从托管代码调用非托管函数的默认约定。2、CharSet控制调用函数的名称版本及指示如何向方法封送String参数。此字段被设置为CharSet值之一。如果CharSet字段设置为Unicode,则所有字符串参数在传递到非托管实现之前都转换成Unicode字符。这还导致向DLLEntryPoint的名称中追加字母“W”。如果此字段设置为Ansi,则字符串将转换成ANSI字符串,同时向DLLEntryPoint的名称中追加字母“A”。大多数Win32API使用这种追加“W”或“A”的约定。如果CharSet设置为Auto,则这种转换就是与平台有关的(在WindowsNT上为Unicode,在Windows98上为Ansi)。CharSet的默认值为Ansi。CharSet字段也用于确定将从指定的DLL导入哪个版本的函数。CharSet.Ansi和CharSet.Unicode的名称匹配规则大不相同。对于Ansi来说,如果将EntryPoint设置为“MyMethod”且它存在的话,则返回“MyMethod”。如果DLL中没有“MyMethod”,但存在“MyMethodA”,则返回“MyMethodA”。对于Unicode来说则正好相反。如果将EntryPoint设置为“MyMethod”且它存在的话,则返回“MyMethodW”。如果DLL中不存在“MyMethodW”,但存在“MyMethod”,则返回“MyMethod”。如果使用的是Auto,则匹配规则与平台有关(在WindowsNT上为Unicode,在Windows98上为Ansi)。如果ExactSpelling设置为true,则只有当DLL中存在“MyMethod”时才返回“MyMethod”。3、EntryPoint指示要调用的DLL入口点的名称或序号。如果你的方法名不想与api函数同名的话,一定要指定此参数,例如:[DllImport(user32.dll,CharSet=CharSet.Auto,EntryPoint=MessageBox)]publicstaticexternintMsgBox(IntPtrhWnd,stringtxt,stringcaption,inttype);4、ExactSpelling指示是否应修改非托管DLL中的入口点的名称,以与CharSet字段中指定的CharSet值相对应。如果为true,则当DllImportAttribute.CharSet字段设置为CharSet的Ansi值时,向方法名称中追加字母A,当DllImportAttribute.CharSet字段设置为CharSet的Unicode值时,向方法的名称中追加字母W。此字段的默认值是false。5、PreserveSig指示托管方法签名不应转换成返回HRESULT、并且可能有一个对应于返回