怎样用VC做ASP的组件

支持支持支持支持支持支持支持支持支持支持支持█████████支持支持支持 

支持支持支持支持支持支持支持支持支持███████████████支持支持 

支持支持支持支持支持支持支持无██████████████████支持支持 

支持支持支持支持支持无████████████████支持支持支持支持支持 

支持支持支持支持███████无███支持█████支持支持支持支持支持无 

支持无████████████支持支持支持████支持支持支持支持支持支持 

无██████████████支持支持支持████支持支持支持支歭支持支持 

无████████████支持支持支持无███████████支持支持支持 

无████████████支持支持支歭██████████████支持支持 

支持██████████支持支持无██████支持无███████支持支持 

支持支持支持支持████支持支持无████支持支持支持█████支持支持无 

支持支持支持支持████支持支持████支持██支持无█████支持支持无 

支持支持支持支持████支持支持████支持████无█████支持支持无 

支持支持支持支持████支歭支持████支持████无█████支持支持无 

支持支持支持支持████支持支持████支持███支持█████支持支持無 

支持支持支持支持████支持支持████支持███支持█████支持支持无 

支持支持支持支持████支持支持████无████支持█████支持支持无 

支持支持支持支持████支持支持████无████支持█████支持支持无 

支持支持支持支持████支持支持████无████支持█████支持支持无 

支持支持支持支持████支持支持████无████支持█████支持支持无 

支持支持支持支持████支持支持███支持████支持█████支持支持无 

支持██支持无█████支持支持███支持███支持无█████支持支持无 

支持██████████支持支持无██支持██支持支持█████支持支持无 

支持无█████████支持支持支持支持███支持支持无████支持支持无 

支持支持无███████支持支持支持支持███无████支持支持支持支持无 

支持支持支持██████支持支持支持无████支持█████支持支持支持无 

支持支持支持支持无███支持支持支持█████支持无███████支持支持 

支持支持支持支持支持支持支持支持██████支持支持无██████支持支持 

支持支持支持支持支持支持支持无██████支持支持支持███████支持无 

支持支持支持支持支持支持支持█████支持支持支持支持无██████支持无 

支持支持支持支持支持支持无█████支持支持支持支持支持无████支持支持 

支持支持支持支歭支持支持███支持支持支持支持支持支持支持无███支持支持

只有个简单DllMain入口函数

使用导出函数关键字_declspec(dllexport)创建DLL(对这个关键字介绍参看下一遍博文吧)。因此新生成Win32Dll.h文件,并在其中用关键字_declspec(dllexport)对要导出函数进行声明

如上所示,我们想偠导出2个函数分别为JustSoSo和Max他们都用关键字_declspec(dllexport)进行了修饰,但是不同是JustSoSo还有用extern “C”进行修饰有什么不同吗?extern “C”修饰时必须吗我们具体来試验一下:

   在工程文件中,首先要定义下我们需要从DLL中调用函数函数指针

调试结果,调用JustSoSo()成功!

调试结果调用Max失败!原因是GetProcAddress返回函数指针为0x.

这是为什么呢?是extern “C”导致吗

调试结果:调用Max成功!

那么,这个extern “C” 是个什么功效呢如何理解这个状况呢?

答:在DLL设计中如果使用C++开发,通常在导出函数定义中使用extern ”C“为什么呢?其实是因为当用户使用“运行时动态链接”时候需要使用GetProcAddress函数来得到导絀函数地址,该函数是通过导出函数函数名定位导出函数而C++编译器因为函数重载原因会对开发者定义函数名进行修饰,导致导出表中函數名通常不是开发者使用函数名比如函数Max可能被修饰成.所以使用extern “C”通知编译器按照C格式进行编译,而不是使用C++方式进行编译(使用VS提供一个工具Dependency Walker可以查看DLL导出函数)

首先,将DLL和LIB文件放置于调用者同一目录下

得到 temp 为 8,使用正确调试成功~!

点击“OK”按钮,选择我们要苼成DLL类型:

在此我们选择第二个选项

然后点击“Finish”按钮。到此我们工程创建就完毕了。

现在我们想把一个add函数作为在DLL外部可以调用导絀函数这次我们采用.def方式来创建DLL

那么首先在.def中田间add函数名:

然后在类中添加add方法:

注意:在函数定义起始需要此语句用来正确地切換MFC模块状态

现在我们用显示连接来调用这个DLL

先进行指针函数定义,然后进行寻址等操作

调试结果:失败了!!在dlladd(2,3)这一步!!这是为什麼呢?


查询资料,有解决办法如下:

使用时函数指针定义也需要注为WINAPI: 

是由于调用接口与原接口参数不一致导致,比如参数不符合或少參数输入导致.

但是我按照提示进行修改声明及函数指针定义

依然是报错,这是为什么啊?

继续查询错误原因资料:

网络上搜索出现此错误原因如下:(和调用约定相关)

1、dll调用时,调用了dll中不存在一个方法出现此种情况,一般是在使用dll时没有把版本搞清楚

2、由于調用接口与原接口参数不一致导致,比如参数不符合或少参数输入导致这种错误方式比较常见

3、在dll中导出函数必须通过def文件来设定(__declspec(dllexport)这樣方式是为用.LIB连接准备),且要声明为WINAPI如:

4、Dll导出函数声明导出方法,与主模块中声明导入方法不一致使得调用时参数传递中,破坏叻调用堆栈出现错误。 

解决方法:请确定导出方(Dll等)与导入方(Exe等)声明保持一致

5、Dll导出函数本身破坏了调用堆栈。编码中最一般錯误比如:对象(如CString)等

解决方法:保证产生对象都被安全释放。

进行调用单步调试发现确实是在传递调用参数时出现问题:

调用时,我传入参数为整数2和3:

F11单步调试进入DLL函数中传入实参发生变化:

参数类型和个数没有误差,那是哪里出问题了聪明你一定发现了,茬DLL中我对all函数声明进行了修改但是定义没有修改,依然是:

这就是问题所在定义时候我依然让他带有"CMFCdll::”,因此进行修改如下(或是 int add(int a ,int b)也鈳):

进行调试,完全正确~~!!!

默认情况下我们函数调用都是遵循__stdcall这个规则。当然也有诸如__cdecl、__pascal等规则。

1、进行函数调用函数参数入棧方式是最右边先入栈。

2、同时__stdcall规定子函数负责栈回收(调用者只负责压栈). 题外话:__pascal调用规则是从左到右,正好与__stdcall相反

    在函数调用过程Φ,会使用栈__stdcall与__cdecl是两种不同函数调用约定,定义了函数参数入栈顺序由调用函数还是被调用函数将参数弹出栈,以及产生函数修饰名方法

在一些地方windows要求必须使用winapi标准,比如说在dll中输出函数(

制作dll 是为了 让其他语言可以调用, 但是呢, 有语言 如delphe 参数调用方法就是 _stadcall……所以,为叻dll 有更好通用性, 一般 都用 WINAPI

现在试试用隐式方式来调用DLL

首先将DLL和LIB文件放到与调用DLLEXE同级目录下

在调用中引入lib库:

结果得出:temp为5,正确~!

ASP是目前一种广为应用用来快速构建动态WEB站点编程语言默认内置开发语言是VBScript,由于ASP和微软Windows系列操作系统结合非常好使得ASP已经成为了NT开发平台上面进行WEB开发首选语言和环境。他有着简单易学方便快速开发种种优点,但是他也有着致命弱点就是他是脚本语言解释执行,速度会受到一定影响更为关键是,使用ASP来开发完成一个项目之后整个项目在交付客户使用时候,是会连带所有ASP脚本源代码也就无法将商业程序保密了,源代码泄漏会給自己造成很大损失虽然微软也相应推出了用来加密ASP程序软件,但是有着诸多限制以及会降低程序运行速度和二次开发调试难度,难噵ASP做出来项目就真要暴露所有源代码吗

  当然了,答案当然是否定因为世界上没有绝对不可能事情,接下来就跟随我来看看如何利鼡VBActiveX DLL来实现将ASP程序封装起来吧也就是我们可以使用ActiveX DLL来完成所有ASP能完成事情,而ActiveX DLL是编译好DLL文件别人是无法得知你源代码,也就保证自己商業机密和核心技术并且达到同样效果,使用完全封装ActiveX DLL会比完全适用ASP脚本语言执行速度要快很多尤其是大运算量时候跟为明显!经过我們具体测试,在操纵10000条数据库记录时候封装成为ActiveX DLLWEB应用程序比纯ASP代码应用程序,速度上面要快大约21%左右在目前国内过于缓慢网络来讲,速度就是一个WEB站点很关键一部分并且采用了ActiveX DLL来开发WEB程序,要比单纯使用ASP好得多毕竟ASP只能使用VBScript来开发,无法享用VB大量优点而ActiveX DLL则可以充汾利用VB里面所有特性。

  下面我们先来看看什么是ActiveX DLL吧ActiveX是微软提出广泛应用于Windows系列一种代码封装技术,提高了程序代码可重用性加快叻程序项目开发速度,一般被称为“组件”在VB6集成开发环境当中,我们可以看到一下几种ActiveX项目:

  这是在“过程外”运行ActiveX/COM服务器组件也就是说他们运行过程和初始化组件客户机代码不同。尽管可以用ASP访问ActiveX EXE但是不推荐改动IIS元库,该库允许所有可执行文件由服务器上运荇脚本代码启动

  这些特殊组件把主机应用程序显示和操作组件所需附加支持包含在GUI环境中。还可以把OCX组件放在网页当中但是,OCX是應用程序界面不可以使用ASP来创建。

  Active文档可以在OLE文件箱应用程序中例如IE或者Office Binder,显示VB表单但他们在ASP不能应用。

  这些ActiveX/COM组件和初始囮组件客户机在同一个进程中运行而我们要讨论ActiveX DLL正是整个组件。一般微软附加组件和其他一些第三方厂家提供各种组件都是这种类型ActiveX DLL泹是并不全是使用VB编写,同样可以使用VC/JAVA等等语言来开发

DLL组件,既然IIS可以初始化这五个组件用于ASP中我们当然也可以直接在我们ActiveX DLL中引用这些组件来实现我们编程,也就是说我们可以在VB应用程序中通过引用这些组件来实现访问ASP内置对象功能

DLL应用中引用这个对象库,通过引用這个对象库我们就获得了一个对象(类):ScriptingContext,这个对象也正是我们整个文章探讨核心对象对象库内关系如下:

  对象库      类        类成员

                    Request

                    Response

                    Session

                    Server

  通过上面关系图,我们就可以很容易理解类ScriptingContent下面我们来看一个具体例子吧:

  '当组件被创建时候会触发这个事件

   '进行对象实例化

  '当组件被销毁时候触发这个事件

  '定义我们自己一個组件方法

  这样,我们就创建可以访问ASP内置对象ActiveX DLL了我们命名这个组件项目为first,在VB中间编译这项目成为一个DLL文件first.dll并且我们在系统中這个DLL文件。接下来我们需要一个简单几乎没有什么代码ASP程序来调用这个组件:

  '创建我们刚才编译成功组件,一旦创建这个组件同時会在叶面输出文字“ActiveX DLL组件已经被

  '注销组件,在注销同时会自动在叶面显示“ActiveX DLL组件已经被销毁!”

  通过上面简单例子,我们可鉯看到使用ActiveX DLL同样可以实现和ASP同样功能并且带来代码保密和程序运行更加高效优点。ActiveX DLL和纯ASP有着各自优点和缺点只要我们合理运用这两种技术,比如适当将商业逻辑封装在ActiveX DLL中或者在需要保密地方使用DLL封装技术,一定可以编写出高效快速WEB应用程序


我要回帖

更多关于 VC水 的文章

 

随机推荐