zoukankan      html  css  js  c++  java
  • P/Invoke .NET调用win32API

    项目:无线无源测温软件系统

             项目中,用到使用P/Invoke在.NET调用win32API,实现对ini配置文件的读写功能!因为有一些配置信息需要保存下来,以便在下一次启动程序完成初始化,这实际上是一种类持久化。将  

             一些信息写入INI文件(initialization file)中,可完成简单的持久化支持。

             

    Windows提供了API接口用于操作INI文件,其支持的INI文件格式一般如下:

    ===============================

    [Section1]

    Key11=value11

    Key12=value12

    [Section2]

    Key21=value21

    Key22=value22

    ...

    [SectionN]

    KeyN1=valueN1

    KeyN2=valueN2

    ===============================

    一般一个INI文件可有N个节,每节可有n个键名及值对应,每个键名及其值以等式形式占一行。

    一般键的名称可任取,不过建议用有意义的字符及词构成。值一般可为整数和字符串,其它类型要进行转换。

    常见的系统配置文件:

    C:/boot.ini

    C:/WINDOWS/win.ini

    C:/WINDOWS/system.ini

    C:/WINDOWS/desktop.ini

    C:/WINDOWS/Resources/Themes/Windows Classic.theme

    注意,字符串存贮在INI文件中时没有引号;key和value之间的等号前后不容空格;注释以分号“;”开头。

    但是令人遗憾的是C#所使用的.NET框架下的公共类库并没有提供直接操作INI文件的类,所以唯一比较理想的方法就是调用API函数。

    然后,.Net框架下的类库是基于托管代码的,而API函数是基于非托管代码的,(在运行库的控制下执行的代码称作托管代码。相反,在运行库之外运行的代码称作非托管代码。)如何实现托管代码与非托管代码之间的操作呢?.Net框架的System.Runtime.InteropServices命名空间下提供各种各样支持COM interop及平台调用服务的成员,

    在受控代码与非受控代码进行交互时会产生一个事务(transition) ,这通常发生在使用平台调用服务(Platform Invocation Services),即P/Invoke

    平台调用是一种服务,它使托管代码能够调用 DLL 中实现的非托管函数,如调用系统的 API 或与 COM 对象打交道,通过 System.Runtime.InteropServices 命名空间

    为了从托管代码中调用非托管的DLL中函数,你要创建一个P/Invoke包装(Wrapper)。一个P/Invoke包装是一个.net兼 容的方法声明,用来创建P/Invoke包装的语法与创建托管方法的声明语法本质上是一样的。唯一不同是P/Invoke包装不包含函数体,而只有方法 名、返回值类型和参数信息。并且,P/Invoke包装使用了DllImport属性。这个属性是用来定位包含有目标函数的非托管的DLL。

    其中最重要的属性之一DllImportAttribute可以用来定义用于访问非托管API的平台调用方法,它提供了对从非托管DLL导出的函数进行调用所必需的信息。下面就来看一下如何实现C#与API函数的互操作。

    读操作:

    [DllImport("kernel32")]
    private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath); 
    section:要读取的段落名
    key: 要读取的键
    defVal: 读取异常的情况下的缺省值
    retVal: key所对应的值,如果该key不存在则返回空值
    size: 值允许的大小
    filePath: INI文件的完整路径和文件名

    写操作:

    [DllImport("kernel32")] 
    private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); 
    section: 要写入的段落名
    key: 要写入的键,如果该key存在则覆盖写入
    val: key所对应的值
    filePath: INI文件的完整路径和文件名
     

    例如: 
    MessageBox在win32的头文件中的声明: 
    int WINAPI MessageBoxA(HWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType); 
    那么我们要在C#中调用这个MessageBox时要这样声明: 
    using System.Runtime.InteropServices; 
    public class Win32 { 
    [DllImport("user32.dll")] 
    public static extern int MessageBox(int hWnd, String text, 
    String caption, uint type); 

    然后可以用常规的.net方法去调用这个MessageBox: 
    public class HelloWorld { 
    public static void Main() { 
    Win32.MessageBox(0, "Hello World", "Platform Invoke Sample", 0); 

    }

    使用 P/Invoke:包括三个主要步骤:声明、调用,以及错误处理

  • 相关阅读:
    CodeForces 1059B
    CodeForces 714A
    浅析母函数
    CodeForces 816C 思维
    CodeForces 816B 前缀和
    CodeForces
    Java项目读取resources资源文件路径那点事
    原型模式
    一次给女朋友转账引发我对分布式事务的思考
    连续最大字段和问题
  • 原文地址:https://www.cnblogs.com/felixzh/p/4308166.html
Copyright © 2011-2022 走看看