动态链接管理

2024-10-06

动态链接管理(共3篇)

动态链接管理 篇1

动态链接库大致可分为两类:系统动态链接库和外部动态链接库。系统动态链接库是由Windows系统提供的, 它包含了大量的供Windows系统和应用程序使用的函数和资源。在系统文件中DLL文件是作为一个单独的程序模块封装起来, 在Windows操作系统中, 最主要的DLL有KERNEL32.DLL、GDI32.DLL和USER32.DLL三个模块, 其中KERNEL32.DLL用来处理存储器低层功能、任务和资源管理等Windows核心服务;GDI32用来提供图形设备接口, 管理用户界面和图形绘制, 包括Windows原文件、位图设备描述表和字体等。而USER32负责窗口的管理, 包括消息、菜单、光标、计时器以及其他与控制窗口显示相关的一些功能。总之, 系统动态链接库中包含了大量的供Windows系统和Windows应用程序使用的函数和资源。使用DLL是多个应用程序可以共享一个DLL文件, 实现资源“共享”, 提高了内存利用率。外部动态链接库则是软件开发人员或编程爱好者根据需要开发的。一个动态链接库实际上是一个函数库, 例如:如果希望通过编程来实现Windows系统的重新启动, 就可以在程序中通过调用系统动态链接库USER32.DLL中的函数Exit Windows Ex来实现;如果要检测一下硬盘的剩余空间, 则可以调用系统动态链接库KERNEL32.DLL中的Get Disk Free Space函数。在软件升级的时候, 开发人员只需要修改相应的DLL文件就可以了, 从而大大提高了软件开发和维护的效率。

1 动态链接库的原理

比较大的应用程序都由很多模块组成, 这些模块分别完成相对独立的功能, 它们彼此协作来完成整个软件系统的工作。可能存在一些模块的功能较为通用, 在构造其他软件系统时仍会被使用。这样就出现了静态和动态的两种链接方式。

1.1 动态链接和动态链接库

动态链接是相对于静态链接而言的。程序设计中, 为了能做到代码和模块的重用, 程序设计者常常将常用的功能函数做成库, 当程序需要实现某种功能时, 就直接调用库文件中的函数, 从而实现了代码的重用。早期的程序设计中, 可重用的函数模块以编译好的二进制代码形式放于静态库文件中, 在MS的操作系统中是Lib为后缀的文件。程序编写时, 如果用户程序调用到了静态库文件中的函数, 则在程序编译时, 编译器会自动将相关函数的二进制代码从静态库文件中复制到用户目标程序, 与目标程序一起编译成可执行文件。这样做的确在编码阶段实现了代码的重用, 减轻了程序设计者的负担, 但并未在执行期实现重用。如一个程序a.exe使用了静态库中的f () 函数, 那么当a.exe有多个实例运行时, 内存中实际上存在了多份f () 的拷贝, 造成了内存的浪费。

随着技术的进步, 出现了新的链接方式, 即动态链接, 从根本上解决了静态链接方式带来的问题。动态链接的处理方式与静态链接很相似, 同样是将可重用代码放在一个单独的库文件中, 所不同的是编译器在编译调用了动态链接库的程序时并不将库文件中的函数执行体复制到可执行文件中, 而是只在可执行文件中保留一个函数调用的标记。当程序运行时, 才由操作系统将动态链接库文件一并加载入内存, 并映射到程序的地址空间中, 这样就保证了程序能够正常调用到库文件中的函数。同时操作系统保证当程序有多个实例运行时, 动态链接库也只有一份拷贝在内存中, 也就是说动态链接库是在运行期共享的。

Windows95/98、NT系列等系统都提供了动态链接库的功能, 并且这些操作系统的系统调用大多都是通过动态链接库实现的KENEL32.dll、USER32.dll、GDI32.dll等动态链接库文件就包含了大量的系统调用。在Windows家族中, NT内核的操作系统在动态链接库机制上较之前的95、98系统要更安全。95、98系统在程序调用动态链接库时, 将动态链接库加载到2GB-3GB之间的被称为进程共享空间的虚拟地址空间, 并且所有进程关于这1GB的虚拟地址空间的页表都是相同的, 也就是说对于所有的进程, 这片共享区的页表都指向同一组物理页, 这样一来, 加载入内存的的动态链接库对所有正在运行的进程都是可见的。如果一个动态链接库被其中一个进程更改, 或其自身崩溃, 将影响到所有调用它的进程, 如果该动态链接库是系统的动态链接库, 那么将导致系统的崩溃。在Windows NT系统中, 动态链接库被映射到进程的用户地址空间中, 并用Copy On Write机制保证动态链接库的共享安全, Copy On Write可以理解为写时拷贝。一般情况下, 多个运行的进程还是按原来的模式共享同一个动态链接库, 直到有进程需要向动态链接库的某个页面写数据时, 系统将该页做一个拷贝, 并将新复制页面的属性置为可读可写, 最后修改进程的页表使之指向新拷贝的物理页。这样无论该进程怎么修改此页的数据, 也不会影响到其他调用了此动态链接库的进程了。

1.2 动态链接库的应用及其优点

为了解决上述问题, 动态链接库技术应运而生, 可以将独立的程序模块创建为较小的DLL (Dynamic Linkable Library) 文件, 并可对它们单独编译和测试。在运行时, 只有当EXE程序确实要调用这些DLL模块的情况下, 系统才会将它们装载到内存空间中。这种方式不仅减少了EXE文件的大小和对内存空间的需求, 而且使这些DLL模块可以同时被多个应用程序使用。Windows自己就将一些主要的系统功能以DLL模块的形式实现。动态链接与静态链接的最大的不同之处在于, 程序要调用的函数并没有包含在程序文件之中, 而是链接到动态链接库文件中。当应用程序运行时, 一旦要用到一个程序文件本身没有包含的函数, 含有这个函数的动态链接库就会被载入, 以便使程序能够访问这个函数。这时, 函数的地址会被解析出来, 并以动态的方式链接到应用程序中。一般来说, 以.dll、.drv、.fon、.sys和许多以.exe为扩展名的系统文件都可以是DLL, DLL是一种磁盘文件, 它由全局数据、服务函数和资源组成, 在运行时被系统加载到调用进程的虚拟空间中, 成为调用进程的一部分。如果与其他DLL之间没有冲突, 该文件通常映射到进程虚拟空间的同一地址上。DLL模块中包含各种导出函数, 用于向外界提供服务。DLL可以有自己的数据段, 但没有自己的堆栈, 使用与调用它的应用程序相同的堆栈模式;一个DLL在内存中只有一个实例;DLL实现了代码封装性;DLL的编制与具体的编程语言及编译器无关。

在Win32环境中, 每个进程都复制了自己的读/写全局变量。如果想要与其他进程共享内存, 必须使用内存映射文件或者声明一个共享数据段。DLL模块需要的堆栈内存都是从运行进程的堆栈中分配出来的。Windows在加载DLL模块时将进程函数调用与DLL文件的导出函数相匹配。Windows操作系统对DLL的操作仅仅是把DLL映射到需要它的进程的虚拟地址空间里去。DLL函数中的代码所创建的任何对象 (包括变量) 都归调用它的线程或进程所有。

使用动态链接方式带来了几大好处:首先是动态链接库和用户程序可以分开编写, 这里的分开既可以指时间和空间的分开, 也可以指开发语言的分开, 这样就降低了程序的耦合度;其次由于动态链接独特的编译方式和运行方式, 使得目标程序本身体积比静态链接时小, 同时运行期又是共享动态链库, 所以节省了磁盘存储空间和运行内存空间;最后一个是增加了程序的灵活性, 可以实现诸如插件机制等功能。用过Winamp的人都知道, 它的很多功能都是以插件的形式提供的, 这些插件就是一些动态链接库, 主程序事先规定好了调用接口, 只要是按照规定的调用接口写的插件, 都能被Winamp调用。

2 创建动态链接库

在创建和调用动态链接库时要用到一些函数调用约定。函数调用约定是指决定函数参数传送时入栈和出栈的顺序, 由调用者还是被调用者把参数弹出栈, 以及编译器用来识别函数名字的修饰约定。

2.1 函数调用约定

2.1.1_stdcall调用约定

它相当于16位动态库中经常使用的PASCAL调用约定。在32位的VC++5.0中Pascal调用约定不再被支持, 取而代之的是_stdcall调用约定。两者实质上是一致的, 即函数的参数自右向左通过栈传递, 被调用的函数在返回前清理传送参数的内存栈, 但不同的是函数名的修饰部分。_stdcall是Pascal程序的缺省调用方式, 通常用于Win32 API中, 函数采用从右到左的压栈方式, 自己在退出时清空堆栈。

2.1.2 C调用约定

即用_cdecl关键字说明, 按从右至左的顺序压参数入栈, 由调用者把参数弹出栈。对于传送参数的内存栈是由调用者来维护的, 正因为如此, 实现可变参数的函数只能使用该调用约定。另外, 在函数名修饰约定方面也有所不同。_cdecl是C和C++程序缺省的调用方式。每一个调用它的函数都包含清空堆栈的代码, 所以产生的可执行文件大小会比调用_stdcal函数的大。函数采用从右到左的压栈方式。VC将函数编译后会在函数名前面加上下划线前缀。它是MFC缺省调用约定。

2.1.3_fastcall调用约定

它的主要特点就是快, 因为它是通过寄存器来传送参数的, 实际上, 它用ECX和EDX传送前两个双字 (DWORD) 或更小的参数, 剩下的参数仍旧自右向左压栈传送, 被调用的函数在返回前清理传送参数的内存栈, 在函数名修饰约定方面, 它和前两者均不同。

关键字_stdcall、_cdecl和_fastcall可以直接加在要输出的函数前, 也可以在编译环境的Setting...C/C++Code Generation项选择。当加在输出函数前的关键字与编译环境中的选择不同时, 直接加在输出函数前的关键字有效。它们对应的命令行参数分别为/Gz、/Gd和/Gr, 缺省状态为/Gd, 即_cdecl。要完全模仿Pascal调用约定首先必须使用_stdcall调用约定, 至于函数名修饰约定, 可以通过其他方法模仿。还有一个值得一提的是WINAPI宏, Windows.h支持该宏, 它可以将导出函数翻译成适当的调用约定, 在Win32中, 它被定义为_stdcall。使用WINAPI宏可以创建自己的API。

2.2 创建动态链接库

在VC中新建一个空的Win32动态链接库工程 (Win32Domanic Library) , 然后添加一个C++Sourse File到工程, 这里的文件名取Dll Export.cpp。在文件中添加如下内容:

接下来编译链接, 就会在debug目录下生成一个调试版本的动态链接库, 该链接库包含了add Func和sub Func两个可供外部调用的函数。在源文件中多了一个没有见过的语句_declspec (dllexport) , 这个语句的作用就是向编译器指出需要在生成的动态链接库中导出的函数, 没有导出的函数是不能被其他程序调用的。要知道一个动态链接库导出了什么函数, 可以在命令提示行用命令“dumpbin-exports Dll Export.dll”来查看。以下是用dumpbin命令查看Dll Export.dll而生成的信息:

编写的动态链接库导出?add Func@@YAHHH@Z和?sub Func@@YAHHH@Z两个函数, 为什么名字不是add Func和sub Func呢?这是因为C++为了支持函数的重载, 会在编译时将函数的参数类型信息以及返回值类型信息加入到函数名中, 这样代码中名字一样的重载函数, 在经过编译后就互相区分开了, 调用时函数名也经过同样的处理, 就能找到对应的函数了。编译器对函数的重命名规则是与调用方式相关的, 在这里采用的是C++的默认调用方式。以此对应的还有stdcall方式、cdecl方式、fastcall方式和thiscall方式, 不同调用方式的重命名规则不一样。

stdcall方式 (标准调用方式) 也即Pascal调用方式, 它的重命名规则是函数名自动加前导的下划线, 后面紧跟一个@符号, 其后紧跟着参数所占字节数, 之所以要跟参数字节数, 是因为stdcall采用被调函数平衡堆栈方式, 用函数名最后的数字告诉编译器需要为函数平衡的字节数。例如, 如果Dll Export.dll采用stdcall方式编译的话, 导出的函数名将会是_add Func@8和_sub Func@8, 而函数编译后的汇编代码最后一句一定是ret8。

cdecl方式即C语言调用方式, 它的重命名规则仅仅是在函数名前加下划线, 因为C语言采用的是调用函数平衡堆栈的方式, 所以不需要在函数名中加入参数所占的字节数, 这样的堆栈平衡方式也使C语言可以编写出参数不固定的函数;同时C语言不支持函数重载, 因此不需要在函数名中加入参数类型信息和返回值类型信息。

3 调用动态链接库

动态链接库已经生成了, 接下来就是调用的工作了。调用动态链接库有两种方式:隐式调用和显式调用, 下面分别来看两种调用方式的具体过程。

3.1 动态链接库的隐式调用

Load-Time Dynamic Linking, 这种用法的前提是在编译之前已经明确知道要调用DLL中的哪几个函数, 编译时在目标文件中只保留必要的链接信息, 而不含DLL函数的代码;当程序执行时, 利用链接信息加载DLL函数代码并在内存中将其链接入调用程序的执行空间中, 其主要目的是便于代码共享。

新建一个空的Win32 Console Application, 命名为Dll Import, 向工程中添加名为Dll Import.cpp的C++Sourse File在文件中写入如下代码:

编译, 没有错误;链接, 有两个错误:找不到外部引用符号。要怎样才能让程序找到动态连接库中的函数呢?这里是关键的一步。到刚才的Dll Export工程目录下, 从debug文件夹中拷贝生成的Dll Export.dll文件和Dll Export.lib文件到Dll Import工程目录。然后依次在VC中选择菜单:Project-->Settings-->Link, 在Object/library Modules中加入一项文件名:Dll Export.lib, 这里的Dll Export.lib并不是静态库文件, 而是Dll Test.dll的导入库文件, 它包含了Dll Export.dll动态链接库导出的函数信息, 只有在工程链接设置里添加了该文件, 才能够使调用了该动态链接库的工程正确链接, 也可以用#pragma comment (lib, “Dll Export.lib”) 预处理命令行来实现。完成以上步骤后, 再编译链接工程, 这次没有任何错误。程序可以顺利调用动态连接库文件, 为了能使程序找到并加载需要的动态链接库, 动态链接库文件必须与调用程序在同一个目录下, 或在path环境变量指定的目录下。

工程中的源文件在调用动态链接库中的函数时, 需要提前声明。声明有两种方式, 一种是传统的extern方式, 一种是_declspec (dllimport) 方式。这两种方式在代码中我均以给出, 其中, 第二种方式能使编译过程更快, 所以推荐使用。

3.2 动态链接库的显式调用

Run-Time Dynamic Linking, 这种方式是指在编译之前并不知道将会调用哪些DLL函数, 完全是在运行过程中根据需要决定应调用哪个函数, 并用Load Library和Get Proc Address动态获得DLL函数的入口地址。比起隐式调用, 显式调用更加灵活, 而且在编译链接时不需要lib导入库文件, 也不需要提前声明函数。通过Windows提供的API函数来动态加载动态连接库并调用其中的函数, 用完后可以马上释放内存中的动态链接库, 十分方便。下面就是显式调用动态链接库的代码:

以上代码并不复杂, 首先定义一个实例句柄用来引用由Windows API函数Load Library加载的动态链接库, Load Library函数的参数是一个字符串指针, 具体调用时需要填入需要加载的动态链接库的位置及文件名, 加载成功后返回一个实例句柄。接下来定义一个函数指针类型, 用该类型声明一个函数指针, 用来存储Get Proc Address函数返回的动态库函数入口地址。Get Proc Address能从指定的动态库中查找指定名字的函数, 如果查找成功则返回该函数的入口地址, 如果失败则返回NULL。有人可能注意到, Get Proc Address函数中指定的函数名是?add Func@@YAHHH@Z, 而不是add Func。这里就和前面将的函数调用方式联系起来, 在Get Proc Address函数中, 指定的函数名必须是编译后经过重命名的函数名, 而不是源文件中定义的函数名。这样实际上给调用带来了相当大的麻烦, 因为不可能去了解每一个经过重命名的导出函数名。好在微软已经给出了解决方法, 那就是在编写动态链接库时同时编写一个以def为后缀的编译命名参考文件, 如果动态链接库工程中有该文件, 则编译器会根据该文件指定的函数名来导出动态库函数。找到需要的动态库函数后, 就可以按需要对它进行调用, 之后调用Free Library函数释放动态库。因为动态库是多进程共享的, 因此调用Free Library函数并不意味着动态库在内存中被释放, 每个动态库都有一个变量用来记录它的共享引用计数, 而Free Library的功能只是将这个记数减1, 只有当一个动态库的引用计数为0时, 它才会被操作系统释放。

3.3 对比

前面已经详细介绍了动态链接库的两种调用方法, 相比之下, 隐式调用在编程时比较简单, 指定导入库文件后, 不必考虑函数的重命名, 就可以直接调用动态库函数。但由于隐式调用不能指定动态库的加载时机, 因此在一个程序开始运行时, 操作系统会将该程序需要的动态链接库都加载入内存, 势必造成程序初始化的时间过长。而显式调用采用动态加载的方法, 用到什么加载什么, 用完即释放, 灵活性较高, 可以使程序得到优化。

4 结语

从动态链接库的产生的需求开始谈起, 主要介绍了Windows动态链接库技术的工作机制优点, 通过举例分析了动态链接库的创建, 及其调用方式等方面, 为利用动态链接库解决工程中问题提供了方便快捷的方法, 同时利用动态链接库也能够实现多平台下的应用, 动态链接库也是开发应用程序技术保密的有效手段, 为工程研究方面提供了技术支持。

摘要:深入分析了Windows动态链接库 (DLL) 内部工作原理, 阐述了DLL的动态链接、地址映射、引用计数等特性, 通过简单实例, 探讨了创建和调用动态链接库的方法和技巧, 为工程人员开发和使用动态链接库提供了一定的技术支持。

关键词:静态链接,动态链接,Dynamic Link Library,隐式调用,显式调用

动态链接管理 篇2

具体步骤如下:

(1)win+r运行输入regedit进入注册表。

(2)依次打开至:HKEY_LOCAL_MACHINESOFTWARE MicrosoftWindowsCurrentVersion ExplorerAlwaysUnloadDLL

注册表编辑器

(3)AlwaysUnloadDLL(字符串值)将其设为1,

大功告成。好像要重起机器。

C#调用动态链接探析 篇3

从Windows操作系统诞生之日起, 就使用动态链接库 (DLL) 来支持公共函数的调用, 区别于在编译时发生、直接把代码插入到程序EXE文件的静态链接。动态链接是指程序运行时才把自己需要的函数链接进来的代码调用方式, 也就是说只要在应用程序需要时, 才加载DLL到进程的虚拟空间, 成为调用进程的一部分。程序使用DLL的优点包括:一方面, 可以减少在磁盘和物理内存中加载的代码的重复量;另一方面, 也可以促进模块式程序开发和简化程序部署和安装。每种编程语言调用DLL的方法都不尽相同, 本文对用C#调用DLL的方法进行介绍。

1动态链接库 (DLL) 的基本分类

每种编程语言调用DLL的方法都不尽相同, 本文只对用C#调用DLL的方法进行分析总结。首先, 需要了解什么是托管, 什么是非托管。随着.net平台的引入, 代码分为托管代码和非托管代码, 托管代码由公共语言运行库环境 (而不是直接由操作系统) 执行的代码。托管代码应用程序可以获得公共语言运行库服务, 例如自动垃圾回收、运行库类型检查和安全支持等。这些服务帮助提供独立于平台和语言的、统一的托管代码应用程序行为。非托管代码指在公共语言运行库环境的外部, 由操作系统直接执行的代码。非托管代码必须提供自己的垃圾回收、类型检查、安全支持等服务;它与托管代码不同, 后者从公共语言运行库中获得这些服务。对于动态链接库DLL来说也分为托管的DLL和非托管的DLL。

2非托管的DLL的C#调用

2.1对于不是基于com的非托管的DLL访问

首先, 应该在C#语言源程序中声明外部方法, 其基本形式是:

[DLLImport (“DLL文件”) ] //-访问DLL文件

修饰符 ReturnType FunctionName (type arg1, type arg2, ...) ;//--声明方法。

其中:DLL文件是包含定义外部方法的库文件。修饰符是除了abstract以外在声明方法时可以使用的修饰符, 一般为public static extern。返回变量类型是在DLL文件中需调用方法的返回变量类型。方法名称是在DLL文件中需调用方法的名称。参数列表是在DLL文件中需调用方法的列表。DllImport还包含了一些可选属性, 其中4个比较常用:

(1) EntryPoint 参数给出 DLL 中入口点的名称。如果未指定 EntryPoint, 则使用方法本身的名称。

(2) CharSet 参数指示用在入口点中的字符集。如果未指定 CharSet, 则使用默认值 CharSet.Auto。

(3) SetLastError 参数指示方法是否保留 Win32“上一错误”。如果未指定 SetLastError, 则使用默认值 false。

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

在使用DllImpor时记得引用所在的命名空间System.Runtime.InteropServices, 同时对于不同类型实现的DLL引用的方法也不尽相同。

2.1.1 引用普通winapi中的方法和自己编写的类库中的普通函数方法

采用DllImport的方法直接导入, 如要调用Winapi中的MessageBoxA功能可以:

[DllImport ("user32.dll", EntryPoint="MessageBoxA") ]

static extern int MsgBox (int hWnd, string msg, string caption, int type)

其它参数采用默认值。如果是自己编写的DLL文件中的函数, 一要注意DLL文件所在的位置, 可以放在项目文件夹下的../bin/Debug/目录里或者放在系统目录C:/Windows/system32里;二要注意DLL文件中使用的参数调用方式。C和C++缺省调用方式是_cdecl?, 而系统默认的方式是CallingConvention.Winapi要改为CallingConvention.Cdecl。

2.1.2 引用类库中类的方法和属性

一种是要在C#中调用类库中类的方法, 通过静态方法导出C++中的方法, 在C#中创建同名的类来接受C++中静态的方法, 注意此时C++类中的方法编译后名称改变, 通过dumpbin命令来查看编译后的名称并进行映射;另一种是要在C#中调用类库中类的属性, 主要使用System.Runtime.InteropServices命名空间的Marshal 类的PtrToStructure方法实现DLL中类的创建, 通过创建的类来实现属性的访问。

2.2对于基于COM的非托管DLL的访问

对于非托管代码下基于COM的DLL, 可以先用tlbimp命令将COM类型中定义转换为公共运行时的等效定义。如:TlbImp test.dll /out: test_clr.dll, 在直接在C#项目中添加对test_clr.dll的引用。然后倒入对应的命名空间, 即可访问COM库的类中方法。如果使用 Visual Studio 开发环境, 则只需添加对COM类型库的引用, VS将为您自动完成此转换。

上面使用的TlbImp.exe (类型库导入程序) , 它是一个包括在 .NET 框架 SDK 中的命令行工具。TlbImp 将 COM 类型库转换为 .NET 框架元数据, 从而有效地创建一个可以从任何托管语言调用的托管包装。用 TlbImp 创建的 .NET 框架元数据可以通过 /R 编译器选项包括在 C# 内部版本中。

注意:在最新的VS2010中直接添加对COM类型库的引用并自动完成此转换后, 要修改DLL的文件引用属性的“嵌入式操作类型”, 由默认的true修改为false, 否则提示无法嵌入互操作类的错误。而在vs2005和vs2008中并无引用属性“嵌入式操作类型”。

3托管的DLL的C#调用

C# 调用托管DLL是很简单的, 只要在“解决方案资源管理器”中的需要调用DLL的项目下用鼠标右击“引用”, 并选择“添加引用”, 然后选择已列出的DLL或通过浏览来选择DLL文件, 最后需要用using 导入相关的命名空间。需要注意的问题也是vs2010中DLL文件引用属性的“嵌入式操作类型”, 也需要由默认的true修改为false。

3.1动态调用托管DLL

C# 动态调用托管DLL也需要借助System.Reflection.Assembly里的类和方法, 主要使用了Assembly.LoadFrom。假如在托管代码的命名空间Test中的Class1类中有Method方法, Method方法有一个int类型参数并返回int的值, 就是假设Method起一个简单的数据处理和返回的作用。编译生成托管的Test.dll文件。在C#项目中要动态引用该DLL, 先导入命名空间:using System.Reflection;在主函数中的调用代码大致如下:

4结语

使用DLL有很多优点, 如:节省内存和减少交换操作;开发大型程序时可以把某些模块分配给程序员, 程序员可以用任何一门所熟悉的语言把该模块编译成DLL文件, 这样可以提高代码的复用, 大大减轻程序员的工作量。所以, 如何灵活地调用DLL应该是每位程序员所熟知的。

本文重点对DLL进行了详细的分类, 对C#访问DLL的方法进行了综合和分析, 提出了调用中要注意的问题。笔者已经在多个项目中使用了上述的访问技术, 提高了工作效率, 缩短了研发周期。

参考文献

[1]潘爱民.COM原理与应用[M].北京:清华大学出版社, 2010.

[2]王小科.C#开发实战宝典[M].北京:清华大学出版社, 2010.

[3]郭新苍, 樊来耀.NET互操作技术研究[J].无线电工程, 2009 (6) .

上一篇:教学体态下一篇:化学实验废液