dll技术(共11篇)
dll技术 篇1
0 引言
水文预报系统通过建立数据库、知识库、方法库、模型库、图形库及综合推理机, 对未来一定预见期内的水文状况做出预测, 对防洪减灾和水资源的优化调度都具有积极的意义。
近年来, 水文预报系统越来越广泛地被应用到许多领域, 如城市防洪、水库调度等。水文预报是相当复杂的过程, 受地理、气候的影响比较大, 且随着气候和地形地貌的变化, 常常需要采用几个模型进行预报并比较。这就要求预报系统具有兼容性和可扩展性。
现行的水文预报模型属于以物理成因为基础, 具有一定经验性的范畴[1]。水文预报系统涉及的内容较多, 从数据采集传输、解析存储、运用水文模型进行计算到最终显示发布, 这些过程若采用同一种程序设计语言, 难以发挥各自的优势。如VB易学易用, 开发出来的软件体积小;VC在底层功能和指针方面的支持较好;C#适用于面向网络的显示和发布。
目前, VB主要用于模型构建和计算, 计算结果通过ASP.Net进行信息发布和与客户端交互。要在整个系统中充分发挥各种语言的优势, 充分利用现有的程序资源, 使用动态链接库 (Dynamic Linking Library, DLL) 是比较合适的方法。
1 DLL技术的优越性
DLL一般以函数库的形式供应用程序调用, 其应用于水文预报系统的优越性主要表现在以下几个方面:
1) 便于不同专业模块的集成。不同专业集成系统往往涉及很多专业应用, 不同的专业适合的语言可能不同, DLL技术通过接口交互, 使得不同专业模块的集成成为可能。如:大坝安全评估、水文预报、水库调度分属不同专业模块, 但相互之间关系密切, 水库调度以水文预报结果为基础, 调度决策又要考虑到大坝安全, 这些不同专业之间的相互调用可通过DLL完成。
2) 便于系统升级。只需在程序升级时, 替换库函数, 不会影响系统其他部分。如:流域气候或下垫面等因素发生变化, 水文预报模型可能会跟着改变, 此时只要将水文预报部分通过DLL替换掉, 与之相关联的其他专业模块不受影响。
3) 提高工作效率。不同语言编写的应用程序都可以使用同一个DLL, 且DLL可与其他程序部分同时进行编程, 可以缩短工期, 提高效率。如:水文预报模块只需提供给水库调度模块DLL函数, 使其得到洪水过程线即可, 模块内部程序不影响调用结构。因此各模块可同步进行编程调试。
4) 节约内存, 提高系统运行速度。DLL只有在被调用时才装入内存运行, 且多个程序使用相同的DLL时, 只需在内存中装载1次, 这样就节省数百兆甚至上千兆的内存开销。
2 用VB创建及测试水文预报模型.DLL
水文预报模型有多种, 基本上都是由模型参数、输入数据、计算流程、输出数据等几部分组成。
下面以水文预报系统的三水源新安江水文预报模型为例编写DLL。
在这个DLL中, 包含了新安江模型水文预报的各个流程, 从设置模型参数、读取实测值到按时段计算, 以及输出计算结果。这些参数值和实测值以虚参数组的形式体现, 调用时, 读取数据库中实际值或用户输入值作为实参数组进行调用, 最后得到计算结果, 这里应用的是洪水流量过程线。
1) 步骤1。启动V B 6.0, 新建工程, 选择Active X DLL, 打开, 工程名改为XAJ, 类模块命名为xinanjiang.dll, 然后定义参数, 并计算:
Public Sub XAJ (xaj_p (15) As float, xaj_i (8) As float, xaj_c (3) As float, p () As float, ep () As float, qq () As float, QR () As float, RR0 As float, N as integer)
其中:xaj_p (15) ——设置模型参数名称;
xaj_i (8) ——设置模型参数值, 可针对地理气候条件交互设置, 针对某个地区一般为常量;
xaj_c (3) ——设置模型启动时起始值, 如根据前期天气情况设置土壤墒情等值;
p () ——实时降雨量, 模拟降雨量;
ep () ——实时蒸发量, 模拟蒸发量;
qq () ——实时区间来水量, 模拟区间来水量;
QR () ——计算出的流量;
RR0——初始流量;
N——实时数据数组的个数
Dim I as integer——设置I为循环变量 (整数型) 。
以下是计算过程, 求出QR () 数据, 返回
For I=1 to N
W (1) =xaj_i (1) :W (2) =xaj_i (2) :W (3) =xaj_i (3)
……
QR (I) = (R+RIMP) *U
Next I
End Sub
完成保存工作后, 选择“文件-生成XAJ.dll”, 确定。
2) 步骤2。文件-添加工程, 选择标准EXE, 打开, 生成窗体form1, 改名为“测试窗口”, 保存。添加测试窗体的目的是为了修改和调试DLL。
3) 步骤3。工程-引用, 在对话框中勾选“XAJ”, 确定。
4) 步骤4。在form1的代码窗口输入:
Private Sub Form_Load ()
…… (定义数据类型)
Dim testxaj As New xinanjiang.dll
Set testxaj=New xinanjiang.dll
…… (读入输入参数)
Call testxaj.XAJ (XAJ_Para, XAJ_Init S, XAJ_Condi, P, EP, q, QR () , mm1)
End sub
5) 步骤5。将测试窗口工程设置为启动工程。运行-启动, 程序自动将计算结果写到相应数据文件中。这里计算结果是写到1个TXT文件里, 如果要写到其他类型的数据库中, 只要在DLL中写数据部分连接不同的数据库, 并按照相应字段写入即可。
6) 步骤6。文件-保存工程组, 组名改为XAJ。下次修改DLL时, 打开XAJ.vbg, 修改后重新编译生成XAJ.dll, 代替原来的DLL文件。调用时, 重复步骤3~5即可。
3 在ASP.Net中调用VB创建的DLL
ASP.Net可以与传统ASP并行运行, 但编程速度远非ASP可比, 用于创建更快、更强大和功能更全的Web应用程序[2]。
1) 步骤1。在开始-运行中输入regsvr32 C:WINDOWSsystem32XAJ.dll, 进行注册。
2) 步骤2。在Calculation.asp中编写代码:
读取数据库:
读取数据表内容:
数据表内容在界面上以表格形式显示, 如表1所示。
计算时, 可以直接采用默认值, 也可以输入参数值, 进行参数设置,
其他水文模型的创建和调用过程类似, 核心就是通过函数调用进行数据的传递, 实现水文预报计算、发布等多个过程的集成, 使之成为一个有机的整体。
4 结语
以上水文预报模型.DLL程序编写和在ASP.Ne中的调用实例证明, 使用DLL技术实现水文预报的方法是切实有效的。使用DLL技术不仅可以利用多种语言各自的优势, 加快系统开发和运行速度, 还能对程序的核心代码进行封装保护, 使得系统更安全[3]、更易于维护和扩展。例如, 在桃山水库洪水预报系统中, 一期工程采用大伙房产流模型和瞬时单位线作为水库流域的产流预报和汇流模型, 后来由于干流入库控制水文站搬迁重建、河道漫滩严重, 因此, 二期工程中, 洪水预报软件进行了升级, 增加了新安江模型和分段分层河道演算模型.DLL。经过对照预报, 发现降雨量大于100 mm时, 大伙房模型比新安江模型合格率高一些;反之, 降雨量小于100 mm时, 大伙房模型比新安江模型合格率低一些。通过总结经验, 提高了水文预报精度。使用了DLL技术后, 系统没有因为增加了模型而变得臃肿耗时, 可见DLL技术对于多模型系统是比较有效的。
摘要:在水文预报系统开发中, 通过DLL技术的应用, 既充分发挥多种开发语言各自的特长, 提高系统开发效率, 又可提高系统的运行速率, 增强系统的可扩展性。详细分析用VB创建及测试水文预报模型.DLL的步骤, 以及在ASP.Net中如何调用VB创建的DLL进行水文预报。程序编写和调用实例证明, 使用DLL技术实现水文预报的方法是切实有效的。
关键词:DLL,VB,ASP.Net,水文预报系统
参考文献
[1]林三益.水文预报[M].2版.北京:中国水利水电出版社, 2001:4.
[2][美]G.Andrew Duthie.ASP.Net程序设计[M].李万伦, 何蕾, 赵海, 译.北京:清华大学出版社, 2002:11-12.
[3]李明刚, 肖健.ASP.Net Web站点高级编程范例[M].北京:清华大学出版社, 2004:1-2.
dll技术 篇2
在系统启动的时候,一个exe程序会将这个dll加载至某些系统进程(如explorer.exe)中运行。
这样一来,普通的进程管理器就很难发现这种病毒了,而且即使发现了也很难清除,
因为只要病毒寄生的进程不终止运行,那么这个dll就不会在内存中卸载,
用户也就无法在资源管理器中删除这个dll文件,真可谓一箭双雕哉。
记得qq尾巴病毒肆虐的时候,就已经有些尾巴病毒的变种在使用这种技术了。
到了初,我曾经尝试着仿真了一个qq尾巴病毒,但独是跳过了dll的远程加载技术。
直到最近在学校论坛上看到了几位朋友在探讨这一技术,便忍不住将这一尘封已久的技术从
我的记忆中拣了出来,以满足广大的技术爱好者们。
必备知识
在阅读本文之前,你需要了解以下几个api函数:
・openprocess - 用于打开要寄生的目标进程。
・virtualallocex/virtualfreeex - 用于在目标进程中分配/释放内存空间。
・writeprocessmemory - 用于在目标进程中写入要加载的dll名称。
・createremotethread - 远程加载dll的核心内容,用于控制目标进程调用api函数。
・loadlibrary - 目标进程通过调用此函数来加载病毒dll。
在此我只给出了简要的函数说明,关于函数的详细功能和介绍请参阅msdn。
示例程序
我将在以下的篇幅中用一个简单的示例virus.exe来实现这一技术。这个示例的界面如下图:
首先运行target.exe,这个文件是一个用win32 application向导生成的“hello, world”程序,
用来作为寄生的目标进程。
然后在界面的编辑控件中输入进程的名称“target.exe”,单击“注入dll”按钮,
这时候virus.exe就会将当前目录下的dll.dll注入至target.exe进程中。
在注入dll.dll之后,你也可以单击“卸载dll”来将已经注入的dll卸载。
模拟的病毒体dll.dll
这是一个简单的win32 dll程序,它仅由一个入口函数dllmain组成:
bool winapi dllmain( hinstance hinstdll, dword fdwreason, lpvoid lpvreserved )
{
switch ( fdwreason )
{
case dll_process_attach:
{
messagebox( null, _t(“dll已进入目标进程。”), _t(“信息”), mb_iconinformation );
}
break;
case dll_process_detach:
{
messagebox( null, _t(“dll已从目标进程卸载。”), _t(“信息”), mb_iconinformation );
}
break;
}
return true;
}
如你所见,这里我在dll被加载和卸载的时候调用了messagebox,这是用来显示我的远程注入/
卸载工作是否成功完成。而对于一个真正的病毒体来说,
它往往就是处理dll_process_attach事件,
在其中加入了启动病毒代码的部分:
case dll_process_attach:
{
startvirus;
}
break;
注入!
现在要开始我们的注入工作了。首先,我们需要找到目标进程:
dword findtarget( lpctstr lpszprocess )
{
dword dwret = 0;
handle hsnapshot = createtoolhelp32snapshot( th32cs_snapproces
暗渡陈仓的DLL木马 篇3
我们平时所见到的木马大多都是可执行文件,这些木马在系统中隐藏自己的本领有限,很容易暴露。而DLL木马则不同,它只有一个文件,依靠动态链接程序库,由某一个EXE做为载体,或者使用RunDLL32.exe来肩动,插入到系统进程中,以达到隐藏自身的目的。因此DLL木马在隐藏技术上比普通小马有了质的飞跃,当然危害性也就大大增加了。下面就让我们通过一款DLL木马“bits”来了解如何防护和清除DLL木马。
什么是DLL木马
DLL(Dynamic Link Library)即系统的动态链接库文件。DLL文件本身不可以运行,需要应用程序调用。当程序运行时,Windows将DLL文件装入内存中,开寻找文件中出现的动态链接库文件。DLL木马实际就是把一段实现了木马功能的代码加上一些特殊代码写成DLL文件,我们知道正在运行的程序是不能被关闭的,而DLL木码插入到一个正在运行的应用程序内存模块中,因此同样死法删除,这就是DLL木马的高明之处。
DLL木马的危害
DLL木马的危害主要分为两方面:一是隐蔽性,由于它可以“寄宿”丁任一应用程序的进程(包括系统进程),因此我们很难发现木马的存在;二是难删除,上文中我们提到被DLL木马插入的进程是无法结束的,因此要想清除它并不容易。
下面结合实例来看看DLL木马的使用和运作过程。bits是一款著名的DLL木马,具备了DLL木马的所有特点,没有进程,也不开肩端口,隐蔽性很强。bits只有一个DLL文件“bits.dll”,运行命令“RUNDLL32.exe bits.dll,install<123456>”即可让bits进驻系统。假设运行bits的计算机IP地址为192.168.0.1,黑客可以使用一款网络工具“no”,在命令提示符中运行它后输入命令“nc 192.168.0.180”,回车后会发现没有回显,此时再输入“123456@dancewithdolphin[xell]:777”才能命令bits。这条命令的作用是绑定一个shell到本机的777端口,此时黑客再连接目标主机的777端口,就可以存目标汁算机上执行任意命令了。一般的DLL木马都需要通过类似方法来安装和使用,虽然比普通木马要来得麻烦,但是威力是相当大的。
bits的清除还是比较简单的,首先运行注册表编辑器,定位到[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasAuto\Parameters],将serviceDLL的键值更改为“%SystemRoot%\System32\rasauto.dll”,然后将系统目录system32文件夹下的bits.dll文件删除即可(如图1)。
DLL木马的防范
DLL木马虽然强大,但是只要注意还是可以防范的。当系统存在问题时,可以使用Windows优化大师的组件“进程管理大师”查看进程中的DLL文件,找出隐藏在其中的DLL木马。在程序上方列表中选中某个进程,再点击下方的“模块列表”标签,列表中就会出现该进程包含的DLL文件。如果是系统进程,那么DLL文件的发行商必是“Microsoft”,否则就很有可能是DLL木马。找到DLL木马后将进程结束,再根据路径删除DLL木马即可(如图2)。
此外,还要及时更新杀毒软件。DLL木马虽然和普通小马不同,但毕竟是木马,还是可以被杀毒软件查杀的,只要我们及时升级杀毒软件病毒库,对防范DLL木马还是有很大帮助的。
dll技术 篇4
Lab VIEW是图形化的开发工具,集成了DAQmx数据采集、VISA串口操作等模块,在硬件控制、网络通信方面功能强大,在虚拟仪器设计和测控软件开发方面已是事实上的工业标准,可以实现软件的快速开发,界面开发简捷。MATLAB具有强大的科学计算机数据处理能力,集合了应用广泛的模块和工具箱强大的计算能力。将两者结合起来混合编程的思想也被越来越多的工程技术人员采纳。在Lab VIEW 8.0以及以后的版本中Lab VIEW已经很好地将MATLAB集成进来。国内的专家学者[1,2,3]在Lab VIEW和MATLAB混合编程方面针对二者早期版本做了大量研究应用工作,而针对二者新版本的研究资料和实现混合编程软件独立于MATLAB独立运行的成功实例较少。本文通过DLL和COM组件两种技术成功实现了Lab VIEW与MATLAB接口编程,解决了混合编程软件独立于MATLAB运行的难题。
1 Lab VIEW与MATLAB接口编程方法
Lab VIEW与MATLAB之间的通信技术主要有下面几种:
(1)动态数据交换(DDE)技术
Lab VIEW提供了DDE通信VI,利用这些VI可以创建DDE Server或DDE Client,完成接收/发送数据、请求/提供服务等功能。
(2)Active X技术(即Automation Server技术)
在LabVIEW中基于Active X实现和MATLAB混合编程的方法又有两种,第一种使用MATLAB脚本节点,第二种使用Active X函数模板。两种方法的基本过程都相同——先打开MATLAB自动化服务器,然后执行MATLAB命令,最后关闭自动化服务器。
(3)动态链接库(DLL)
将DLL和MATLAB计算引擎(基于COM技术)结合起来,把调用MATLAB计算引擎的C代码编译成DLL供Lab VIEW调用。另外一种方法是通过MATCOM插件将MATLAB的M文件编译成C++代码,这些代码能被C/C++编译器VC++6.0编译成DLL文件,合理设计输入输出参数,就可以在Lab VIEW中通过调用库函数节点方便地调用,且脱离了MATLAB运行环境,执行效率高。
(4)COM组件技术
从6.5版本开始,MATLAB提供了COM生成器。它能把MATLAB开发的算法做成组件,这些组件作为独立的COM对象,可直接被其他支持COM的语言所引用。Lab VIEW 5.0及以上版本支持COM。利用COM组件技术的Lab VIEW和MATLAB联合开发的应用程序运行效率高,而且非常利于用户应用软件的独立发布。
动态数据交换(DDE)技术、Active X技术和MATLAB计算引擎(调用MATLAB计算引擎的C代码编译成DLL供LabVIEW调用)的最大缺点是不能脱离MATLAB工作环境。DLL技术(基于MATCOM插件)和COM组件技术都可以实现用户应用软件的独立发布。文献[4]利用DLL技术实现了Lab VIEW和MATLAB混合编程,文献[5]进行了Lab VIEW调用MATLAB COM组件的技术研究。上述研究都是在较低级版本的开发环境下实现的。本文通过例子分别介绍利用DLL技术(基于MATCOM插件)和COM组件技术实现Lab VIEW和MATLAB混合编程。开发环境如下:MATLAB R2007a,Microsoft Visual C++6.0,MATCOM 4.5,Lab VIEW 8.5。
2 Lab VIEW和MATLAB混合编程技术实现
打开MATLAB新建一个m文件命名为slidaver,函数的功能是实现滑动平均消除信号趋势项。输入参数sample Value是一维数组,slidstep是滑动阶次;输出参数slidaver Value是信号滑动平均后返回数组。M文件内容如下:
function slidaver Value=slidaver(sample Value,slidstep)
clc
l=slidstep;
x=sample Value;
n=length(x);
b=ones(1,l);
a=[b*x(1),x,b*x(n)];
b=a;
for k=1:l
for j=l+1:n-l
b(j)=mean(a(j-l:j+l));
end
a=b;
end
slidaver Value=x(1:n)-a(l+1:n+l);
2.1 基于DLL混合编程
2.1.1 使用MATCOM插件生成DLL
首先安装MATCOM 4.5,安装成功后,运行VC++6.0,并从菜单中选择Tools->Customize->Add-ins and Macro Files,选择Browse,改变文件类型为Add-in(.dll),选择MATcom45binmvcide.dll文件,确定。在VC++6.0的开发环境中可以看到Visual MATCOM工具条。新建Win32 Dynamic-Link Library工程,命名为myslidaver,创建A simple DLL project。点击MAT-COM工具条Add m-files to current project把slidaver.m文件添加到新建工程。在myslidaver.cpp文件添加#include″matlib.h″,#include″slidaver.h″,编译,在slidaver.h中同样要添加#include″matlib.h″,否则将提示错误。在myslidaver.cpp中添加数据处理代码,返回double型数据slidaver Value和采样数组sample Value以指针的形式传递,添加一个表示数组长度的变量len。全部代码如下:
#include″stdafx.h″
#include″matlib.h″
#include″slidaver.h″
BOOL APIENTRY Dll Main(HANDLE h Module,
DWORD ul_reason_for_call,
LPVOID lp Reserved
)
{
return TRUE;
}
extern″C″_declspec(dllexport)void libslidaver(double*slidaver Value,double*sample Value,int slidstep,int len)
{
init M(MATCOM_VERSION);//初始化matlib库
Mm a1,x1;//使用矩阵类Mm构造矩阵a1,x1.
a1=zeros(1,len);
for(int i1=1;i1<len+1;i1++)
a1(1,i1)=sample Value[i1-1];
x1=slidaver(a1,slidstep);
for(int i=1;i<=x1.rows();i++){
{
for(int j=1;j<=x1.cols();j++)
slidaver Value[i-1,j-1]=x1.r(i,j);
}
exit M();
return;
}
程序中涉及到了两个成员函数.rows()和.cols(),它们分别返回矩阵的行数和列数;x1.r(i,j)代表矩阵x1的第i行第j列的元素。编译运行后在Release文件夹下产生myslidaver.dll。
2.1.2 Lab VIEW调用DLL
打开Lab VIEW新建一个vi,在程序框图面板添加调用库函数节点,函数配置选板如图1所示。
程序框图如图2所示,返回值slidaver Value需要赋初值,否则将会产生调用错误。为了在客户端应用还要在Release文件夹下添加ago4501.dll,v4501v.dll,v4501v.lib,matlib.h四个文件。
2.2 基于COM组件混合编程
2.2.1 com组件编译生成
在MATLAB命令行(>>)输入deploytool命令;打开Deployment Tool页面,选择工具栏第一项新建工程(Create a new deployment project),在弹出的New Deployment Project左边一栏选择MATLAB Builder for.NET,在右边栏中选择Generic COM Component,在Name栏中输入工程名称myslidaver.prj,并为工程选择路径,注意工程保存路径中不能出现汉字,否则在后续生成时会出现错误,如图3所示。
在新页面中选择工具栏Add File,为新建工程添加M文件,然后选择工具栏中的Build the project,生成myslidaver_1_0.dll。点击工具栏中的Package the project,在distrib文件夹下生成_install.bat,myslidaver_pkg.exe两个文件,若要在没有安装MAT-LAB的机器上调用此DLL,需要运行_install.bat或myslidaver_pkg.exe即可把组件注册到机器上,供客户端程序调用[6]。
2.2.2 Lab VIEW调用COM组件
打开Lab VIEW新建一个vi,在程序框图面板中添加互联接口|Active X|打开自动化,在其输入引脚自动化应用句柄右击选择Active X类,浏览找到myslidaver_1_0.dll,选中myslidaverclass并点击确定按钮,如图4所示。
把打开自动化输出引脚右击创建myslidaver.Imyslidaverclass类的方法选择slidaver方法,方法节点下nargout参数表示输出参数个数,此处设为1;输出参数slidaver Value输入端右击创建一个常量即可;信号数组sample Value和滑动阶次slidstep可以与节点下对应的参数直连;slidaver Value虽然在MATLAB中是一维矩阵类型,但是转到Lab VIEW中要把它当成二维数组处理,slidaverValue输出端需要加入变体至数据转换函数,函数类型要用double型二维空数组初始化。程序框图具体如图5所示。
2.3 DLL技术和COM组件技术比较
由于MATCOM最终版本为4.5,对MATLAB 6.5及以前的版本提供了较好的支持,可以方便地实现M文件到C++文件的转换。但是在MATLAB 6.5以后版本没有提供同步更新,对后续版本引入的新函数和标识无法识别,因此基于MATCOM生成DLL供Lab VIEW调用的方法只适用于MATLAB 6.5和以前版本及部分后续版本函数。基于COM组件的调用技术,是Math Works公司当前主推的接口技术,需要MATLAB运行时库MCR(MATLAB Components Runtime)的支持,适用于MATLAB6.5以后的版本。MCR的功能是提供MATLAB发布程序的运行底层支持,它打包了MATLAB运行所必需的支持全部库、组件,因而可以运行几乎所有支持编译的MATLAB及工具箱命令,只是初始化时间比以前要慢得多。笔者用上述两种方法调用MATLAB提供的wden函数都没有成功,因此MATLAB中的一些函数即不支持生成DLL也不支持生成COM组件。
3 结语
基于DLL技术和COM组件技术混合编程的方法的最大优点就是可以创建独立的应用程序,而且在执行效率方面明显改善。基于DLL混合编程技术,不需要安装MCR,适合MATLAB6.5版本(及后续版本部分函数)的用户。基于COM组件的技术具有极佳的应用前景,需要额外安装MCR支持。开发者可以根据应用特点选择其中一种使用。基于DLL技术和COM组件技术混合编程的方法,可以将Lab VIEW和MATLAB各自的优势结合起来,开发出功能更强大、性能更优越的测控软件。
参考文献
[1]徐晓东,郑对元,肖武.LabVIEW8.5常用功能与编程实例精讲[M].北京:电子工业出版社,2009.
[2]曲丽荣,胡容,范寿康.LabVIEW、MATLAB及其混合编程技术[M].机械工业出版社,2011.
[3]王济,胡晓.MATLAB在振动信号处理中的应用[M].北京:中国水利水电出版社,知识产权出版社,2006.
[4]彭宇宁,朱后.利用DLL技术实现LabVIEW和MATLAB混合编程[J].计算机与现代化,2007(144):93-95.
[5]胡吉朝,傅钥,王定远.LabVIEW调用MATLAB COM组件的技术研究[J].IT技术论坛,2008(26):71-72.
dll技术 篇5
系 统文件rpcss.dll是存放在Windows系统文件夹中的重要文件,通常情况下是在安装操作系统过程中自动创建的,对于系统正常运行来说至关重要,在正常情况下不建议用户对该类文件进行随意的修改,它的存在对维护计算机系统的稳定具有重要作用。
rpcss.dll文件基本信息:
DLL 文件: rpcss 或者 rpcss.dll
DLL 名称: Remote Procedure Call subsystem
描述:
rpcss.dll是分布式COM服务相关文件。
属于: Windows
系统 DLL文件: 是
常见错误: File Not Found, Missing File, Exception Errors
安全等级 (0-5): 0
间谍软件: 否
广告软件: 否
木马/病毒:否/可能
rpcss.dll文件安全分析:
rpcss.dll病毒会通过替换系统“rpcss.dll”文件来实现开机自启动。是一个专门窃取QQ网络游戏帐号的木马程序。同时,它还会窃取QQ网络游戏用户的密码保护资料。
中毒现象:
1、杀毒后系统不能上网。
2、杀毒后系统粘贴功能失效。
3、杀毒后系统任务栏上的部分信息不能正常显示。
4、杀毒后系统桌面程序“explorer.exe”启动非常慢,等好长时间才能显示出来桌面。
rpcss.dll出错的修复方法:
软件修复
rpcss.dll出错,很多是因为系统中了流氓软件,如果不了解系统,不知道rpcss.dll在电脑中的存放位置,那么建议使用修复工具对系统进行最全面的扫描和修复。
首先,建议使用金山毒霸。
然后,点击主界面的快速扫描,进行全面的系统扫描。
最后,按提示重新启动电脑,rpcss.dll下载修复完毕,
下 载修复
一、如果您的系统提示“没有找到rpcss.dll”或者“缺少rpcss.dll”等类似错误信息,请把rpcss.dll下载到本机
二、直接拷贝该文件到系统目录里:
1、Windows 95/98/Me系统,则复制到C:Windows/System目录下。
2、Windows NT/系统,则复制到C:WINNTS/system32目录下。
3、Windows xp系统,则复制到C:Windows/System32目录下。
三、然后打开“开始-运行-输入regsvr32 rpcss.dll”,回车即可解决错误提示!
手动删除该病毒的方法步骤(经过实操测试绝对有效):
1、删除病毒文件“C:DOCUME~1ADMINI~1LOCALS~1Temp~*.tmp”、“C:WINDOWSsystem32 gdipro.dll”、“C:WINDOWSsystem32drivershm17002.sys”、“C:WINDOWS system32sys17002.dll”、“C:WINDOWSsystem32sys17002.add”、“C:WINDOWS system32rpcss.dll”
2、把系统文件“C:WINDOWSsystem32srpcss.dll”改名为“C:WINDOWSsystem32rpcss.dll”。
3、把注册表“HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesrpcssObjectName”键值改为“NT AUTHORITYNetworkServic e”。
4、把注册表“HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesrpcssParametersServiceDll”键值改为“%SystemRoot%system32rpcss.dll”。
5、重新启动计算机系统,系统杀毒修复完毕(系统重新启动后就可以上网了,粘贴功能有效了,同时任务栏的显示也正常了)。
6、使用杀毒软件进行全盘查杀病毒(该病毒为木马下载器下载到您计算机中的病毒,那个木马下载器还下载了N多其它病毒也同时安装到了您的计算机系统中)。
dll技术 篇6
我使用的是Windows XP SP2系统,最近不知道什么原因,每次启动系统后,系统会自动弹出一个错误提示框,内容为“加载c:progra~1deskto~1castdmipn.dll时出错”,将其关闭后系统可以正常运行。虽然不影响系统,但每次启动系统都出现非常烦人。请问如何将其去除?
答:这是一款名为“桌面传媒”的广告软件被卸载或是被其他工具删除后而在注册中遗留有相关信息的原因。解决方法:单击“开始→运行”,输入“msconfig”并运行,在打开的窗口中选择“启动”选项卡(如图),找到与其相关的项目并将其删除即可。另外,也可以直接在注册表编辑器中依次展开“HKEY_LOCAL_MACHINESOFTWARE Microsoft Windows CurrentVersion RUN”项找到相关的项目并将其清除即可。
Q2、修改卡巴斯基升级方式
我使用的是卡巴斯基5.0版的杀毒软件,由于电脑现在暂时不能上网,需要从其他电脑中将升级包拷贝到本机再升级。请问,如何才能让卡巴斯基直接从本地文件夹中升级呢?
答:这个问题困扰了很多CFan的读者,我们已经收到几封提这样问题读者的来信了,问题其实很好解决,就在这里一并回答了。打开卡巴斯基主窗口,再打开“设置”选项卡,单击“设置更新”,在打开的窗口中将“更新源”设置为“从本地文件夹”,再单击“设置”按钮设置存放更新文件的目标文件夹即可。
Q3、如何在Word中输入单词的音标
我现在需要编辑一份含有英文单词音标的文档,在Word中找了半天都没找到输入音标的方法。请问,如何才能正确地为英文单词添加上标准的音标?
答:如果你安装了金山词霸(也可以直接将金山词霸的安装文件中的“Xdictksphonet.ttf”安装到系统中),之后,就可以直接在Word 中选择“插入→符号”,打开“符号”对话框选择字体项里选“Kingsoft Phonetic Plain”,接下来便可以在下面的列表中发现需要的音标符号了。
Q4、如何彻底卸载 RealOne Player 播放器
我的Windows XP SP2系统中原先安装过RealOne Player播放器,后来不知道被谁卸载掉了,但是卸载时没有卸载干净,我现在重新安装RealOne Player时,系统总是提示让我把旧版本的文件删除干净,接着就退出安装程序。我进入控制面板中的“添加或删除程序”也无法找到卸载项,到注册表中把所有与Real OnePlayer相关的项目都删除了,问题依旧。请问如何解决?
答:其实,RealOne Player播放器自带了卸载功能,用这个卸载功能可以彻底将其从系统中清除掉。方法是:在资源管理器中打开“C:Program FilesRealRealOne PlayerSetup”(这是默认的RealOne Player安装目录,如果安装时将其安装到其他文件夹,请酌情处理)文件夹,然后运行下面的“r1pclean.exe”程序,运行后输入“Y”,回车,再输入“Y”,再回车即可。
Q5、在MyMPC中无法看字幕
不知道什么原因导致我安装的MyMPC播放器无法看到字幕,重新安装也无法解决问题。请问该如何解决?
答:首先,尝试单击“开始→程序→MyMPC音视频解码包→设置工具→VobSub设置”,在打开的设置窗口中正确地设置字幕项。如果还不能解决问题,那就可能是因为你是升级安装MyMPC而导致的问题,可以通过下面的方法来解决:
将其卸载,之后再重新安装,在选择组件时,别管他提示关于Vodsub已经安装或尚未卸载的信息,选中Vodsub项并完成安装。如是还不行,再试试重新注册VSFilter.dll文件:从http://www.hanzify.org/index.php?Go=Show::List&ID=7668下载下来将其复制到%windir%system32 文件夹下,然后在“开始→运行”对话框中输入:regsvr32 vsfilter.dll 即可。
Q6、让译典通(Dr.eye)支持Acrobat Reader
我现在安装了译典通翻译工具,而我经常使用Acrobat Reader阅读器阅读PDF文档。请问,如何让译典通支持Acrobat Reader阅读器中打开的PDF文档中的翻译?
答:将译典通安装到系统中后,找到安装目录(或是安装文件中)中的“Dreye40.api”文件,并按照你的Acrobat Reader版本将其拷贝到相应的目录即可:
Acrobat 6.0 Reader 版用户:“C:Program FilesAdobeAcrobat 6.0Readerplug_ins”下 。
Acrobat 6.0 完整版用户:“C:Program FilesAdobeAcrobat 6.0Acrobatplug_ins”下 。
Acrobat 7.0 Reader版用户:“C:Program FilesAdobeAcrobat 7.0Readerplug_ins”下 。
软件脱壳之DLL文件脱壳 篇7
关键词:脱壳,DLL文件,重定位表
很多软件在开发完成之后通常会进行加壳操作,我们可以把壳看成一个子程序,由它处理后的Pe文件在磁盘中一般是以加密后的形式存在的,有的壳还带有压缩功能,使得exe文件更加小巧,加壳在一定程度上可以防止破解者对程序文件的非法修改,同时可以防止程序被反编译;壳附加在原程序上通过Load载入内存后,却抢先于原程序执行,也就是在PE文件代码段执行之前抢先得到控制权;然后在执行过程中对原PE文件加密,还原,还原后在把控制权交还给原程序。
在我们进行逆向分析这些软件的时候,就会遇到壳的阻碍,因此我们需要把原程序从壳中分离出来,也就是我们常说的脱壳。脱壳的方法与工具有不少,本文要分析的是DLL文件的脱壳方法。
DLL文件的脱壳与EXE文件步骤差不多,所不同的是,DLL文件多了个基址重定位表等要考虑。
一种常用解决办法是,利用外壳重定位相关数据时,会根据外壳转储的重定位表确定要重定位的RVA,完成代码重定位工作。将这些要重定位的RVA提取出来,再将这些RVA根据重定位表的定义重新生成一份新的重定位表。
加壳的DLL处理重定位表有以下几种情况:
1)完整的保留了原重定位表;
2)对原重定位表进行了加密处理;
ASPack,ASProtect等壳属于第1种情况,没有加密重定位表,脱壳后,只需找到重定位的地址和大小即可。而UPX,PECompac等壳属于第2种情况,必须重建重定位表,这也是本文所要讨论的,本文以UPX为例来讲述一下重定位的重建。
用UPX v3.01将EdrLib.dll文件加壳,用PE工具查看其PE信息。
EntryPoint:E640h
ImageBase:400000h
1寻找OEP
当DLL被初次映射到进程的地址空间中时,系统将调用DllMain函数,当卸载DLL时也会再次调用DllMain函数。也就是说,DLL文件相比EXE文件运行有一些特殊性,EXE的入口点只在开始时执行一次,而DLL的入口点在整个执行过程中至少要执行两次。一次是在开始时,用来对DLL做一些初始化。至少还有一次是在退出时,用来清理DLL再退出。所以DLL找OEP也有两条路可以走,一是载入时找,另一方法是在退出时找。而且一般来说前一种方法外壳代码较复杂,建议用第二种方法。
UPX壳比较简单,往下翻翻,就可看到跳到OEP的代码:
代码:
2 Dump映像文件
停在OEP后,运行LordPE,在进程窗口选择loaddll.exe进程,在下方窗口中的EdrLib.dll模块上单击右键,执行“dump full”菜单命令,将文件抓取并保存到文件里。
对于DLL文件来说,Windows系统没有办法保证每一次运行时提供相同的基地址。如果DLL基址所在内存空间被占用或该区域不够大,系统会寻找另一个地址空间的区域来映射DLL,此时外壳将对DLL执行某些重定位操作。此时DLL被映射到内存的地址是03D000h,与EdrLib.dll默认的基址400000h不同,被重定位项所指向的地方是已经重定位了的代码数据。
例如这句:
代码:
003D1266 A1 58B43D00 mov eax,dword ptr[3DB458]
为了得到与加壳前一样的文件,必须找到重定位的代码,跳过它,让其不被重定位。重新加载DLL,对上句重定位的地址3D1267h下内存写断点,中断几下,就可来到重定位的处理代码。
代码:
UPX壳己将原基址重定位表清零,重定位操作时,使用其自己的重定位表。地址3DE7B4h处ESI指向UPX0区块的VA,本例为3D1000h,为了让代码以默认ImageBase的值400000h重定位代码,可以在这句强制将ESI的值改为401000h。来到这句后,双击ESI寄存器,改成401000h,然后按F4来到3DE7C7h这时。此时代码段的数据没被重定位,可以Dump了。
代码:
003D1253 833D 68AD4000 00 cmp dword ptr[40AD68],0
运行LordPE将DLL映像抓取,并保存为upx_dumped.dll。
3重建DLL的输入表
ImportREC能很好地支持DLL的输入表的重建,首先,在Options里将“Use PE Header From Disk”默认的选项去除。这是因为ImportREC需要获得基址计算RVA值,DLL如果重定位了,从磁盘取默认基址计算会导致结果错误。
1)在ImportREC下拉列表框中选择DLL装载器的进程,此处为loaddll.exe进程。
2)单击“Pick DLL”按钮,在DLL进程列表中选择EdrLib.dll进程。
选择DLL进程
3)在OEP处,填上DLL入口的RVA值1240h,单击IAT AutoSearch按钮获取IAT地址。如果失败,必须手工判断DLL的IAT位置和大小,其RVA为7000h,Size为E8h。
4)单击“Get Import”按钮,让其分析IAT结构重建输入表。
5)勾选Add new section,单击“Fix Dump”按钮,并选择刚抓取的映像文件dumped.dll,它将创建一个dumped_.dll文件。
4构造重定位表
我们先来回顾一个重定位表的结构:
代码:
重定位表以1000h大小为一个段,因为ItemOffset最长为12位,即刚好为1000h。如果还有更多段,将重复上面数据结构,直到VirtualAddress为NULL,表示结束。
ReloREC工具可以根据一组重定位的RVA,重新构造一个新的重定位表。首先要做的工作是将UPX外壳这些要重定位的RVA提取出来。
在处理重定位代码语句中,下面这句就是对代码重定位,其中EBX保存的就是要重定位的地址。
代码:
0 0 3 DE7B6 mov dword ptr[ebx],eax;EBX指向要重定位的RVA
补丁的思路是找块代码空间,跳过去执行补丁代码,将重定位的地址转成RVA,并保存下来。如下语句跳到补丁代码处:
代码:
3 E0000h这个地址是OllyDbg的插件HideOD临时分配的,其初始值设为3 E0010h。
补丁代码键入完成后,外壳在处理重定位相关代码时,这段补丁代码将需要重定位的RVA全部提取出来。执行完补丁代码,数据窗口将保存需要重定位的RVA,
将需要重定位的RVA复制出来(选取数据时,最后一个DWORD数据是0),操作时单击鼠标右键,执行菜单Binary/Binary copy(二进制复制)功能,再运行WinHex,新建一文档,将这段二进制数据粘贴进去,粘贴时,选择ASCII Hex模式,然后将提取的数据保存为Relo.bin。
Relo.bin中保存的就是需要重定位的地址,以RVA表示。部分数据如下:
代码:
ReloREC这款工具,就是根据这些RVA重新生成一份新的重定位表
准备工作完成,运行ReloREC,将Relo.bin拖放到ReloREC主界面上可打开此文件。然后在dumped_.dll里找一块空白代码处保存重定位表(一般在UPX1或UPX2区块里找),在这选择C000h处。在Relocation's RVA域里填上原始重定位表的RVA地址,本例为C000h,最后单击“Fix Dump”按钮,打开上述刚修复输入表的dumped_.dll文件,即可完成重定位表的修复。
参考文献
[1]阿锋.一“脱”到底—浅析软件脱壳[J].玩电脑,2005(6):43-44.
dll技术 篇8
在Power Builder中可以定义两种类型的外部函数, 即全局外部函数与局部外部函数。全局外部函数是指在应用程序中的任何位置均可以调用的函数;局部外部函数是指只能在特定的窗口、菜单、用户对象中调用的函数。
若外部函数无返回值或者返回值为VOID, 则需要用SUB-ROUTINE关键字代替FUNCTION关键字。另外, 若DLL中的名字不是在程序中引用的名字或数据库中的函数名, 则在Power Srcipt中不合法, 须指定ALIAS FOR来建立Power Srcipt名字与外部名字之间的联系。
当定义局部函数时, 需指定函数的访问级别, 即限定哪些程序可以访问该函数。局部外函数可使用的访问级别有三种, 分别为Public、Private和Protected。其中, Public函数所有应用程序可以引用;Private函数的引用范围仅限于本对象, 对象的子类对象不可引用;Protected函数可在定义对象及其子类对象中引用。
2、Power Builder与DLL之间的参数传递
外部函数的参数引用须符合P a s c a l规则, 在缺省情况下, Power Builder是通过“值传递”的形式来完成与DLL间的数据传递, 即Power Builder将对需传递的参数备份一份拷贝, 然后通过堆栈将这份拷贝传递给被调用函数。如果我们希望DLL中的函数可以改变调用参数的“原值”, 则可通过修改传递法则来实现, 即在参数类型前面加关键字“REF”进行参数声明。
3、使用DLL的基本规则
在Windows中, DLL被装入内存后只存在一个系统实例, 操作系统不会因为多个程序使用同一个DLL而在内存中产生多个DLL副本。每个DL L只有一个最大为64K的数据段。在默认情况下, Power Builder都是使用“值传递”来传递参数。若在定义外部函数时使用了REF关键字, 则操作系统将传32位的地址指针 (即段地址+偏移量, 而不是只传偏移量) 给Power Builder调用函数, 从而确保存DLL函数能够正确找到Power Builder对应的数据地址。
事实上, Power Builder所使用的数据类型与C语言的数据类型并不完全相同, 因此, 对于C语言中不支持的数据类型应在调用函数前进行格式的转换, 具体见参考文献[1]。另外, Windows中某些数据类型C语言也不支持, 这种情况需要在C预编译时用TYPEDEF作预定义, 而Power Builder调用其函数时也要作适当的格式转换。
4、保护模式下函数调用
Power Builder程序若访问不属于当前应用程序的内存, 可能会导致DLL保护模式出错。此时, 需重点检查以下三个方面的问题:
(1) 是否向DLL函数传递了错误格式的参数。这种调用方式出错概率较大, 又由于Power Builder调试器不能跟踪到C语言程序中, 因此这种的错误很难发现。如果怀疑参数格式错误, 可以在C语言中使用Message Box函数显示调用参数的方法来检查参数的传递是否正确, 更全面的方法是使用Windows的调试版本 (带有调试信息的Windows环境) 以及功能更强的调试工具 (如, Soft-ice、Code View) 进行调试观察。
(2) 是否在C语言中引用了超出Power Builder范围的数组申请。由于C语言并不检测数组的范围, 这也是导致DLL发生保护模式错误发生的常见原因。
(3) 是否使用了已释放了的内存指针。为了避免出现这种错误, 好的做法是在程序中把已经释放了的内存指针设置为NULL, 便于程序在再次使用时的分析判断。
5、关于远指针和静态变量的使用
在C语言中, 所有的静态变量和全局变量都是在程序的数据堆中分配的, 而其它变量是在栈中分配的。由于DLL只有数据段, 而没有自己的堆栈段, 因此在使用时它调用程序的堆栈。这就意味着寄存DS指向的是DLL数据段, SS指向Power Builder应用程序的堆栈。一般而言, 普通Windows应用程序由于DS和SS相同, 允许使用近指针, 但如果Power Builder程序调用DLL中的远堆变量, 则在编程时必须使用32位的远指针, 否则程序会出错。因此, 如果Power Builder调用与内存寻址有关的C函数, 在没有把握的情况下应使用C语言中的FAR版本。
另外需要注意的是, 不管有多少实例调用同一个DLL, 实际上在内存中只有一份DLL代码。实际上, Windows是面向多任务的操作系统环境, 除了Power Builder应用程序用, 其它程序也有可能调用的该DLL的实例, 因此, 就需要充分考虑DLL中的静态变量被修改的问题。
6、使用外部函数应注意的地方
(1) 不要共享文件句柄。这是因为每个应用程序都有各自的文件句柄表, 如果两个应用程序通过一个DLL来访问同一个文件, 它们势必会分别打开这个文件。因此, 不能在Windows环境中共享文件句柄。
(2) 及时释放已使用过的资源。这是个比较容易忽略的问题, 特别是在GDI环境中使用DLL函数, 一定要及时释放它们, 否则可能会由于申请GDI资源失败而导致Windows死机。例如, 在程序中创建并实例化一个OFFI CE对象 (VB A对象) , 在使用完后, 应用Delete Object函数来删除它。
(3) 配置正确的库搜索路径。在程序中, 外部函数一旦被声明和引用, 就必定会搜索DLL的安装路径, 缺省路径是应用程序的当前目录, 也可以把DLL安装到Windows目录和WindowsSystem32目录中。
参考文献
[1]邢小平, 谢国珍.PB调用API函数剖析[J].电脑学习, 2010, 2:87-8 8.
[2]马贵安.PowerBuilder Win32API函数调用参考手册[M].北京:清华大学出版社, 2007.
小议VC中的动态链接库Dll 篇9
隐藏进程的技术中,最常见的一种就是钩子程序。钩子是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。钩子程序运行时虽然看不到,但是人们很容易从它的藏身处发现他的静态版本-以exe结尾的可运行程序。在这种时候,动态链接库Dll应用其中,人们就很难发现该程序的本来面目了。实际上,Dll的作用绝不仅仅是为了隐藏木马,它在windows编程中发挥着非常重要的作用。论文从几个角度对windows编程的Dll技术进行研究。
1. 库与动态链接库DLL
1.1 库的概念
在刚学习计算机编程的时候,一定会接触到库的概念。它本质上是让人们能够重用他人的代码,减小工作量产生的。计算机编程中的库有如下的两个特点:(1)库是独立存在的,编写库的程序和编写一般的程序区别不大,只是库不能单独执行;(2)库提供一些可以给别的程序调用的东西,别的程序要调用它必须以某种方式指明它要调用之。
1.2 DLL原理
动态链接程序库(Dynamic Link Library简称DLL)作用在于为应用程序提供扩展功能。应用程序想要调用DLL文件,需要跟其进行动态链接。所谓的动态链接是指在程序运行时才把DLL中的代码加入到程序的运行中,而静态链接库在编译的时候就已经加入到了程序中。
2. DLL库的应用及分类
从编程的角度,DLL应用程序需要知道DLL文件导出的API函数才能调用。所以DLL文件本身并不可以运行,需要应用程序调用。程序的发布上,DLL和静态lib也是有差别的。对于静态lib来讲,程序在编译成可执行文件时会把静态链接库中的程序拷进可执行文件中,所以Lib文件是不用同可执行文件一同发布的。而链接到动态库DLL中时要通过一个Lib文件,Lib文件保存了函数或类在DLL中的入口地址,可执行文件中相应存放的也是函数地址,所以DLL和Lib要同可执行文件一起发布。实际上只要遵循约定的DLL接口规范和调用方式,用各种语言编写的DLL都可以相互调用。Windows提供的系统DLL(其中包括了Windows的API),在任何开发环境中都能被调用。而在VC中支持的DLL一般包括三种:Non MFC DLL,Regular DLL,Exetension DLL。下面对这三种类型的DLL进行简要的介绍。
(1)Non MFC DLL(非MFC动态链接库):不使用MFC类库结构,直接用C写,输出函数用标准C接口,能被非MFC程序调用
(2)Regular DLL正则动态链接库:使用MFC编写,源文件中有继承自CWin App的类,只能被MFC调用;正则Dll又分成静态连接到MFC的和动态链接到MFC的,在创建时会看到。
(3)Extension DLL扩展动态链接库:实现从MFC继承下来的新类,输出MFC新子类,只能被MFC调用。
3. 简单DLL的编程
下面用一个简单的例子,来展示在vc++中如何创建DLL工程。在新建菜单中选择新建工程Win32 Dynamic Link Library,选择simple project,加入自己的函数My Function:
4. DLL的调用
库分为静态库与动态库DLL,深入到DLL内部,其调用方式也分为静态与动态。
4.1 静态调用
动态链接库DLL的静态调用方式的顺利进行需要完成两个动作:(1)告诉编译器与DLL相对应的.lib文件所在的路径及文件名,#pragma comment(lib,"dll Test.lib")就是起这个作用。程序员在建立一个DLL文件时,连接器会自动为其生成一个对应的.lib文件,该文件包含了DLL导出函数的符号名及序号(并不含有实际的代码)。在应用程序里,.lib文件将作为DLL的替代文件参与编译。(2)声明导入函数,extern"C"__declspec(dllimport)add(int x,int y)语句中的__declspec(dllimport)发挥这个作用。静态调用方式不再需要使用系统API来加载、卸载DLL以及获取DLL中导出函数的地址。这是因为,当程序员通过静态链接方式编译生成应用程序时,应用程序中调用的与.lib文件中导出符号相匹配的函数符号将进入到生成的EXE文件中,.lib文件中所包含的与之对应的DLL文件的文件名也被编译器存储在EXE文件内部。当应用程序运行过程中需要加载DLL文件时,Windows将根据这些信息发现并加载DLL,然后通过符号名实现对DLL函数的动态链接。这样,EXE将能直接通过函数名调用DLL的输出函数,就象调用程序内部的其他函数一样。
4.2 动态调用
由“Load Library-Get Proc Address-Free Library”系统API提供的三位一体“DLL加载-DLL函数地址获取-DLL释放”方式,这种调用方式称为DLL的动态调用。动态调用方式的特点是完全由编程者用API函数加载和卸载DLL,程序员可以决定DLL文件何时加载或不加载,显式链接在运行时决定加载哪个DLL文件。
5. 总结
在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll和gdi32.dll,windows的大多数API都包含在这些DLL中。应用号DLL,可以大大增强编程的灵活性,但DLL概念负责,应用方式很多,只有通过不断地练习才能掌握。
参考文献
[1]王挺、周会平、贾丽丽等编著,c++程序设计[M]清华大学出版社,2005.
直升机虚拟仪表DLL设计与实现 篇10
直升机CBT系统主要采用计算机仿真、计算机控制和图像处理显示等高新技术,实现一个融图形、图像、文字、曲线、图表、声音为一体的多媒体仿真平台。它可以为飞行员提供多方位的信息流,充分发挥飞行员多感官接收信息、应用信息的能力。
直升机CBT系统的组成包括主控计算机系统、网络通讯系统、环境音响系统、座舱、航电及操纵系统、视景系统等。座舱、航电及操纵系统采用软硬结合的方法进行设计,座舱中仪表板和中央操纵台上的分立仪表均为触摸响应的虚拟仪表,用GL Studio进行虚拟仪表开发。座舱结构、座椅、飞行操作联动机构、驾驶杆、总距杆等均做成硬件结构,通过网络将硬件机构的控制信号传给主控计算机进行处理。
直升机CBT系统中的分立仪表有气压高度表、空速表、陀螺地平仪、综合显示器、多功能键盘、油量控制板等,下面将详细介绍虚拟仪表DLL的设计开发过程,以及在GL Studio中进行调用的方法。
1 GL Studio开发平台简介
直升机本文基于仿真平台GL Studio,其是Disti公司为仪表仿真软件开发提供的一套系统解决方案。用户可以利用其图形交互界面以所见即所得的方式完成仪表面板的制作,通过其代码编辑器完成仪表内部的逻辑仿真。其代码生成器能够将用户的制作结果自动生成C++和OpenGL源代码,用户既可以将代码进行单独编译,也可以嵌入到其他程序中进行编译,从而避免了大量繁琐的底层OpenGL开发过程[2,3,4,5]。
GL Studio工程可以生产两种类型的文件:一种可执行文件.exe;另一种是可独立使用的文件即DLL[6]。在用GL Studio进行直升机CBT系统中虚拟仪表开发的时候,各分立仪表都做成单独的DLL,将虚拟仪表的输入和输出接口定义为属性。在最后的主程序开发时,只需在GL Studio的图形界面上插入各虚拟仪表DLL,根据飞行模型的需要传递参数即可。GL Studio开发虚拟仪表DLL的流程如图1所示。
2 创建虚拟仪表DLL
2.1 制作纹理
制作纹理有多种方法,一般采用数码相机拍摄实物照片,然后运用图形编辑软件处理。获取高质量的实物照片是制作纹理的关键,所以在拍摄直升机座舱仪表照片时需要设置好背景,调节好光线,选取合适的角度。制作纹理时,将仪表照片经过图形编辑软件处理后保存为*.png格式[7]。
在进行纹理制作的过程中,采用3D MAX和Photoshop制作仪表纹理非常方便。以直升机仪表中最常见的气压高度表为例,介绍仪表纹理的制作过程。
首先,在3D MAX中,创建一个圆柱体作为盘底,再创建一个白色的小长方体作为长刻度。调整好长方体大小,将旋转轴心设为表盘中心。选择工具中的阵列选项,设置好旋转角度为36°,阵列维数为1D,数量10,按确定。同理阵列出短刻度。对立体图进行渲染,保存为*.png格式。用Photoshop打开进行编辑,添加相应的刻度数字。这种方法制作出来的表盘非常美观,而且比处理仪表照片的效率高。
2.2 设计图形界面
设计图形界面即创建仪表模型,创建的模型分为静态模型和动态模型。以气压高度表为例,高度表盘为静态模型,仪表上的指针、旋钮、气压表盘为动态模型。
GL Studio设计器支持的所见即所得绘制方式,使开发仪表工作变得简单、直观。在GL Studio中进行绘制图形和添加纹理。纹理添加完毕后,注意调整各元件之间的层次关系,确定图形的正确显示[7,8,9,10,11]。仪表界面的最终效果如下,给气压高度表每个独立的部件进行合理命名,以方便行为代码的编写。
场压选择旋钮的制作方法:在设计面板“Geometry”栏中,高亮“PBS”点功能键“Converts Selected to GlsKnob”创建旋钮。右击生成的旋钮,在“Knob”选项卡中设置旋钮转动的角度及连续性。
2.3 定义接口
气压高度表只有一个输入接口:气压值。最少只需要添加一个属性,Baro_hPa(),通过飞行动力学模型给该属性接口传值,单位统一为hPa。
2.4 编写行为代码
气压表左下角的旋钮为场压选择旋钮。仪表右边的气压表盘会随着场压选择旋钮转动指示设定的场压值。添加变量PBS_hPa,该变量记录设定的场压值。
(1)场压选择旋钮代码编写。
旋钮的位置范围为0~100,用来设定场压PBS_hPa,气压修正范围为950~1 050 hPa。在设计气压高度表的时候,假设初始场压在1 013 hPa。
> 场压选择旋钮的初始化代码
self->PositionVal(63.0f);//旋钮初始位置设为63PBS_hPa=950.0+(self->PositionVal());//63.0对应场压1 013 hPa
PBSDisc->DynamicRotate(2.4*self->PositionVal(),Z_AXIS);
//气压刻度盘初始旋转角151.2°,即1 013 hPa气压值所在角度
> 场压选择旋钮回调函数代码
if (ObjectEventIs(ev,"PositionVal"))
{
PBS_hPa=950.0+(self->PositionVal());
//旋钮位置范围0~100,对应的气压修正范围为950~1 050 hPa。
PBSDisc->DynamicRotate(2.4*self->PositionVal(),Z_AXIS);
//气压刻度盘通过换算在0~240°逆时针旋转,与气压表盘950~1 050 hPa场压对应
}
(2)Baro_hPa()属性函数编写。
Baro_hPa()为输入接口,用来接收主程序传来的外界气压大小(静压)。3 000 m以下,每升高12 m气压下降133.3 Pa。通过静压和旋钮设定的场压,即可算出直升机所在的高度。
> Baro_hPa()属性函数的行为代码
_baro_hPa=value;
float altitude=(PBS_hPa*100-_baro_hPa*100)*12.0/133.3;//通过静压和场压差算出高度
float alt_long=(float)fmod(altitude,1 000.0f);
longNeedle->DynamicRotate(-(alt_long*(360.0/1 000)),Z_AXIS);//长指针根据高度值大小旋转,1 000 m转动360°
float alt_short=(float)fmod(altitude,10 000.0f);
shortNeedle->DynamicRotate(-(alt_short*(36.0/1 000)),Z_AXIS);
//短指针根据高度值大小旋转,1 000 m转动36°
2.5 生成代码、发布DLL
选择菜单栏中code->Generate All生成代码,在Microsoft Visual Studio.NET 2003中选择编译选项为Live Component Release,编译、连接,即可生成气压高度表DLL,在Licensed LiveComponent Release文件夹下可以找到生成的Barometric Altimeter.dll。
3 DLL的加载
3.1 插入虚拟仪表DLL
在程序中,有以下两种加载动态链接库的方式:隐式链接和显式加载[12]。而GL Studio中对DLL的加载方式更加简便,程序员不需要了解底层的加载方式即可对DLL进行操作。
在工具栏中点击“(Inserts a Component)”,选中需要加载的仪表DLL,即可将该虚拟仪表插入到GL Studio编辑器中。调整该虚拟仪表的大小,放到仪表板底板合适的位置。插入进来的虚拟仪表DLL实际上是一个类对象指针。
3.2 给虚拟仪表DLL传递参数
插入虚拟仪表DLL并进行合适的命名后,剩下的工作就是在Calculate()对该虚拟仪表的接口进行读写操作,即传递控制参数。
在GL Studio中,Resource()函数可以读写DLL的属性,这也是在创建虚拟仪表DLL的时候将所有输入输出接口定义为属性的原因。调用方式如下:
someObject->Resource("someAttribute")>>someValue;//将虚拟仪表的某个属性读取出来
someObject->Resource("someAttribute")<<someValue;//给虚拟仪表的某个属性传值
在总仪表板程序的calculate()中给各虚拟仪表DLL传递参数,以model_作为前缀的变量是根据直升机飞行动力学模型解算出来的值:
Bool model bPower=true;//电源信号
//-------气压高度表-----------------------------
_BarometricAltimeter->Resource("Baro_hPa")<<model_Baro;
//-------起落架状态指示灯--------------------------
_LGearStatus->Resource("bPower")<<model_bPower;
_LGearStatus->Resource("bJianCha")<<_AlarmPanel->Resource("bJianCha");//将信号灯盒DLL的“bJianCha”属性的值传递给起落架状态指示器DLL的“bJianCha”属性。即将信号灯盒上的检查按钮的状态传递给起落架状态指示灯,控制其亮。
……
3.3 调试并完善
在项目后期联合调试和完善的过程中,如果需要对某个仪表的功能进行修改和扩充,只需要修改该虚拟仪表的程序代码,编译连接生成新的DLL。用新的DLL替换原有的DLL文件即可。
4 结束语
dll技术 篇11
DLL从本质上来说是一个包含有函数或者数据的程序模块,它可以被可执行文件或者是其他的DLL所调用,向应用程序提供函数、类或者其他各种资源。DLL技术具有的优点为:
(1) 当多个应用程序调用同一个DLL时,在内存中只有一个实例,能高效经济地使用内存;
(2) DLL实现的代码封装性好,使得程序简洁明晰;
(3) DLL的编制与具体的编程语言及编译器无关,只要遵守DLL的开发规范和编程策略,并安排正确的调用接口。不管用何种编程语言编制的DLL都具有通用性。
DLL是软件工程模块化思想的具体体现,它使得功能模块能够很容易地更改和重复使用;并且在几个应用程序同时使用同一个功能模块时,可以有效地减少系统开销,也是更为抽象的COM技术的实现基础,具有很高的使用价值。
1 C++Builder中DLL的创建及调用
1.1 DLL的创建
1.1.1 创建DLL工程
C++ Builder已经为创建DLL提供了非常方便的方法。选择C++ Builder中的菜单File/New/Other,然后在NewItems窗口中选择DLL Wizard图标。此时,会弹出如图1所示的对话框。
根据编写DLL所需用的源程序语言,选择Souece Type类型为C或者C++。
若编写的DLL模块内包含有VCL,则复选UseVCL选项。复选该选项后,C++ Builder将自动在头文件中包含“vcl.h”。而如果没有复选Use VCL,在日后也可以手动将“vcl.h”添加到程序的头文件中。如果要产生一个包含CLX的DLL,就应该复选Use CLX。
C++Builder会自动建立一个DLL工程,将其保存为NewDLL.cpp。如果复选了VC++ Style DLL,则C++ Builder将会自动产生一个Visual C++风格的DLL主函数:
1.1.2 编写DLL函数
一般,在DLL中定义的函数,有部分是供外部应用程序所使用,这部分函数称为引出函数。在C++ Builder 6中,引出函数可作如下形式的声明:
extern "C"_declspec(dllexport)_stdcall<函数值类型> <函数名> (参数表)
其中:_declspec(dllexport)是引出函数的修饰符._stdcall关键字强迫编译器使用标准的调用协议来生成函数调用。在DLL源程序中,引出函数的定义形式如下:
_declspec(dllexport) _stdcall<函数值类型> <函数名> (参数表)
{
函数体
}
下面以一个简单的“计算圆的面积”的函数来简要说明DLL函数的编写。
在上述代码中,CircleArea是导出函数,可供调用DLL的外部程序使用;而Radius是内部函数,它不能被调用DLL的外部程序使用,其编写方法与普通函数没有区别。
1.2 DLL的调用
DLL包括静态和动态调用两种方式。两种方式具有不同的优点。静态调用方式程序简单明了,其编写过程如同调用内部的函数模块一样;但在静态调用时,DLL在程序开始执行时就自动载入,占用较多的系统资源。而动态调用方式仅仅在需要的时候才将DLL调入内存,这样能够减少对系统资源的占用,需要付出的代价是调用的过程要稍微复杂一些。
1.2.1 创建及添加导入库
在C++ Builder 6中,无论采用何种链接方式,都需要用于包装DLL的库,即导入库。利用C++ Builder 6创建导入库。选择菜单Project/Options,接着在弹出的对话框中选择Linker选项卡,复选Generate import library。这样,在编译DLL时,在产生DLL的同时就会自动产生同名的导入库。
在导入库产生后,若某个工程要调用该DLL,就必须将其对应的导入库添加到该工程中。选择菜单Project/Add to project,在弹出的Add to project对话框中,选择文件类型为:Library file(*.lib),选中.lib文件即可。
1.2.2 DLL的静态调用
静态调用DLL需要三种文件,分别是需调用的DLL文件,该DLL对应的输入库(.lib)文件以及该DLL对应的头文件(.h)。即在应用程序中增加以下两行,就可以像调用普通函数一样直接调用NewDLL中的导出函数:
#include"NewDLL.h"
#pragma link"NewDLL.1ib"
1.2.3 DLL的动态调用
动态调用DLL不需要包含DLL的头文件,也不需要链接动态库。但必须知道要调用的函数名称与参数类型,使用WindowsAPI函数LoadLibrary()函数调用DLL。然后用API函数GetProcAddress()取得指向被调用函数的指针,即可对DLL导出函数进行调用。当DLL使用完毕后,用函数FreeLibrary()释放DLL。这三个Windows API的声明如下:
HINSTANCE LoadLibrary(LPCTSTR lpLibFileName);
该函数用于将lpLibFileName指向的可执行模块载入到调用进程的地址空间中,函数需要一个指向已载入模块的句柄。
FARPROC GetProcAddress(HMODULE hModule,LPCSTR lpProcName);
该函数用于从一个已经载入的模块中取得指定名称的函数的地址,“hModule”表示DLL模块的句柄,“lpProcName”表示函数名。
BOOL FreeLibrary(HMODULE hLibModule);
该函数将指定DLL的引用次数减1,“hLibModule”表示要被卸载的DLL模块的句柄。如果成功,FreeLibrary()返回true,否则返回false。
下面为调用NewDLL中的导出函数CircleArea的程序代码段:
由于DLL可由多个程序共享,当加载或释放DLL时,操作系统并没有真正地进行相应的操作,而只是对DLL的引用次数进行加或减1。当某个DLL被首次载入内存时,操作系统将此DLL的引用次数记为1。之后,若有另一程序载入该DLL,操作系统并不重复载入该DLL,而是将其引用次数加1,并共享此DLL在内存中的原来副本。相反,当需要释放某个DLL时,操作系统对其引用次数减1,当某DLL的引用次数减为0时,操作系统才真正释放该DLL。
2 C++Builder 6如何调用Visual C++6.0的DLL
C++Builder是一种面向对象的、可视化的快速应用程序开发环境。在建立用户接口时,不必编写程序描述输入或输出接口的外观和配置,只要使用控件便可实现,是属于一种所见即所得的直观式设计概念。使用C++ Builder可以以最少的手工编写的代码,创建出高效的32位窗口应用程序。当使用Visual C++和MFC类库进行Windows编程时,由于MFC在类层次封装了大量Windows SDK函数和典型Windows应用的缺省处理,用户只需要较少的编程就可以实现自己的开发任务,能够大幅度提高开发速度和效率。因此,在实际应用中,可以使用C++ Builder编写精美的窗口界面,而使用Visual C++创建高效的DLL实现两者之间的相互调用。
2.1 用VC编写一个DLL
选择菜单new/project,选择Win32 dynamic-link library,命名为NewDLL,选择a simple DLL porject。在NewDLL.cpp中加入如下代码:
编译生成NewDLL.dll
2.2 用C++Builder隐式调用NewDLL.dll
选择project/Add to Project,文件类型选择Library file,将NewDLL.lib加人到工程中,将NewDLL.dll放到程序当前目录,并在要调用该DLL的.cpp文件中加入如下代码:
extern“C” double _stdcall CircleArea(double r);
然后就可以直接在需要调用该DLL中的CircleArea函数的地方直接调用了。
3 创建及调用DLL应注意的问题
创建及调用DLL应注意的问题有:
(1) 在C++Builder中,四种调用修饰符分别是:_cdcel,_fastcall,_pascal,_stdcall。当修饰符缺省时,则默认为_cdcel;
(2) 为了能够在C++Builder中正确调用VC DLL,需在函数说明时使用_stdcall修饰符。在第2.1.1节中,如果NewDLL中是VC DLL。则应将typedef double (*NewDLL_function)(double);变为typedef double (_stdcall *NewDLL_function)(double);即在说明函数指针时,要明确函数修饰符为_stdcall;
(3) 所有dll函数均以C方式创建,即必须以extern “C”创建并调用,不论实现是.C 还是 .CPP;
(4) 函数声明必须指定_decl(dllexport)关键字,否则必须写.def文件才能生成正确的DLL及其引入库,在调用函数时无需该关键字;
(5) 所有未经关键字导出的类都只能作为DLL内部类使用。当然外部仍然可以使用被内联的成员函数(该成员函数不应该调用任何未经导出的函数或者类成员函数)。
(6) 在DLL中声明的全局变量可以被DLL中的函数正常调用,但不能被外部程序调用,但在外部程序中声明的变量可以作为参数传递给DLL。
4 结 语
在此介绍了在C++ Builder 6开发平台中如何创建及调用其自身的DLL,以及如何调用由Visual C++ 6.0所生成的DLL。 在进行跨平台混合编程时,一定要注意函数调用的约定修饰,特别要注意混合编程语言的缺省设置。当调用出现问题时,首先要注意调用约定是否一致,如不一致,则应首先保证函数标识符及参数传递相同。
参考文献
[1]胡晓明.基于Windows的DLL编程及应用[J].现代电子技术,2005,28(10):55-57.
[2]王西武,阎梅,张殿富.Windows环境下动态链接库(DLL)程序设计[J].现代电子技术,2004,27(16):32-33,36.
[3]李湘江.基于汇编语言的32位DLL程序的创建[J].科学技术与工程,2007(10):5 112-5 115.
[4]叶文.C++Builder中创建可被VC++程序调用的DLL的方法[J].重庆科技学院学报:自然科学版,2005(7):81-83,98.
[5]饶万成.DLL在VC++编程中的应用[J].黑龙江科技信息,2007(5):82-87.
[6]费佩燕,闫允一,郭宝龙.VC++中动态链接库的实现[J].现代电子技术,2003,26(8):9-11.
[7]郭勇鹏,陈业夫,马懿超.VC++中DLL的应用[J].应用科技,2004,31(1):44-46.
[8]胡家民.可视化软件开发环境中的DLL编程技术[J].电讯技术,1999,39(6):37-39.
[9]李幼仪,甘志.C++Builder高级应用开发指南[M].北京:清华大学出版社,2002.
【dll技术】推荐阅读:
追根溯源:DLL技术木马进程内幕大揭密06-09
技术合同:技术转让技术秘密合同07-03
技术与科学技术07-24
节能技术的技术划分09-05
蔬菜施肥管理技术技术06-01
环保技术节能技术09-15
信息技术整合电子技术09-27
质量技术监督信息技术10-08
医疗技术消毒技术规范05-31
技术革新和技术改造08-29