平台启用服务

来源:互联网 发布:lte-scdma是什么网络 编辑:程序博客网 时间:2024/04/28 00:57

net平台启用服务(platform invocation Services,也称为PInvoke)允许受控代码与从dll导出的函数和结构一起工作。

(1)声明导出的dll函数

特性被用于为类型提供设计时刻的信息。通过反射,这些信息可以再运行时刻被查询,C#也是利用特性来能够向编译器藐视将要被调用的dll函数。如下所示:

[DllImport(params)]

accessmodifier static extern retValue dllFunction(paras);

dllImport具有以下几个参数:

a、CallingConvention 参数指示入口点的调用约定。如果未指定 CallingConvention,则使用默认值 CallingConvention.Winapi。

  

此成员可以含有以下值:

Winapi:此成员实际上不是调用约定,而是使用了默认平台调用约定。在windows上默认为stdCall,在wCE上默认为Cdecl

Cdcel:调用方清理堆栈,可以调用具有varargs的函数,可接受可变数目的参数的方法

StdCall:被调用方清理堆栈

ThisCall:第一个蚕食是this指针,它存储在寄存器ECX中,其他参数被推送在堆栈上,此调用约定多用于从非托管dll导出的类调用方法。

fastcall不支持此调用约定 

如: [DllImport("msvcrt.dll",CharSet=CharSet::Ansi,CallingConvention=CallingConvention::Cdecl)]
   static int printf( String^ format, int i, double d );
   [DllImport("msvcrt.dll",CharSet=CharSet::Ansi,CallingConvention=CallingConvention::Cdecl)]
   static int printf( String^ format, int i, String^ s );
 
b、CharSet 指示如何向方法奉送字符串参数,并控制名称重整。ExactSpelling 字段会影响 CharSet 字段在确定要调用的入口点名称时的行为。如果未指定 CharSet,则使用默认值 CharSet.Auto。

     此值具有如下成员:

   Ansi:以多字节字符串的形式封送字符串

  Unicode:以Unicode2字节形式奉送字符串

   Auto:针对目标操作系统适当地自动封送字符串,在windows NT,2000,xp和2003默认值为Unicode,在Windows 98和me上默认值为Ansi,使用语言可以重写此默认值。


c、EntryPoint 参数给出 dll 中入口点的名称。如果未指定 EntryPoint,则使用方法本身的名称。 指定入口点名称时,您可以提供一个字符串来指示包含入口点的 DLL 的名称,或者也可以按序号来标识入口点。序号以 # 符号为前缀,如 #1。


d、ExactSpelling 参数指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配。如果未指定 ExactSpelling,则使用默认值 false。


e、PreserveSig 指示是否直接转换具有 HRESULTretval 返回值的非托管方法,或是否自动将 HRESULTretval 返回值转换为异常。如果未指定 PreserveSig,则使用默认值 true。

// Use the DllImportAttribute to import the SHAutoComplete function.
    // Set the PreserveSig to false to specify exception errors.
    [DllImportAttribute("shlwapi.dll", EntryPoint = "SHAutoComplete", ExactSpelling = true, PreserveSig = false)]
    public static extern void SHAutoComplete(IntPtr hwndEdit, SHAutoCompleteFlags dwFlags);

    // Use the DllImportAttribute to import the SHAutoComplete function.
    // Use the default value of the PreserveSig field to specify HRESULT errors.
    [DllImportAttribute("shlwapi.dll", EntryPoint = "SHAutoComplete", ExactSpelling = true)]
    public static extern int SHAutoCompleteHRESULT(IntPtr hwndEdit, SHAutoCompleteFlags dwFlags);


f、SetLastError 参数指示方法是否保留 Win32"上一错误"。如果未指定 SetLastError,则使用默认值 false。

g、BestFitMapping 将Unicode字符转为ANSI字符时,启用或禁用最佳映射行为。 
此外,用 DllImport 属性修饰的方法必须具有 extern 修饰符。

 

(2)回调函数

C#程序不仅可以调用一个dll函数,而且dll函数也可以在回调场景中调用C#方法。定义dll函数及委托——调用dll函数——实例化委托来实现的。

 

(3)汇集和PInvoke

每次调用一个dll函数时,net必须吧参数汇集到被调用函数,并且把值返回给进行调用的net程序。net已经为每一种net类型定义了一个默认的本地类型。

但是,可以使用MarshallAs特性覆盖默认的net汇集行为。

例如:

[DllImport("user32.dll")]

static extern int MessageBox(int hwnd,[MarshallAs(UnmanagedType.LPWStr)string msg,[MarshallAs(UnmanagedType.LPWStr)string caption);

 

 

 

原创粉丝点击