VC程序如何设置编译才能在运行时根据选择调用函数名相同的不同版本的libdll文件?

VC程序如何设置编译才能在运行时根据选择调用函数名相同的不同版本的libdll文件?,第1张

你讲了半天,我更混乱了。给你个变通的方法

比如现在有dll:dll1、dll2、dll3……

他们都有函数void func(int)

我假设你已经把所有dll中的函数导入到了程序中:

func1、func2、func3

现在定义函数指针数组:

typedef void(*array)(int)

array funcarray[3]

funcarray[0]=func1

funcarray[1]=func2

funcarray[2]=func3

然后就可以根据情况调用函数了;

比如,先定义一个全局变量:int select

界面上有按钮btn1、btn2、btn3

点击btn1则select=1;……

//int param

调用函数funcarray[select](param)

如果还是不大清楚,可以查阅一下函数指针数组的资料

对于你的问题补充,你可以设置断点调试一下。断点一个设置在加载dll和加载dll中函数的地方,看下加载返回的dll句柄与函数句柄是否有效;另一个设在调用地方,查看的东西一样。这样就可以知道问题所在了啊。

这我也没帮办法了,抱歉~~

c++ 调用.lib的方法:

一: 隐式的加载时链接,有三种方法

1  LIB文件直接加入到工程文件列表中

在VC中打开File View一页,选中工程名,单击鼠标右键,然后选中"Add Files to Project"菜单,在d出的文件对话框中选中要加入DLL的LIB文件。然后在首先要使用该函数的地方加上该LIB的头文件,如#include "..\lib.h"即可(没有头文件当然就不用了)。

2  设置工程的 Project Settings来加载DLL的LIB文件

打开工程的 Project Settings菜单,选中Link,然后在Object/library modules下的文本框中输入DLL的LIB文件,如you.lib(或者lib文件的路径,包括文件名)。然后在首先要使用该函数的地方加上该LIB的头文件,如#include "..\lib.h"即可(没有头文件当然就不用了)。

3  通过程序代码的方式

加入预编译指令#pragma comment (lib,"*.lib"),这种方法优点是可以利用条件预编译指令链接不同版本的LIB文件。因为,在Debug方式下,产生的LIB文件是Debug版本,如Regd.lib;在Release方式下,产生的LIB文件是Release版本,如Regr.lib。然后在首先要使用该函数的地方加上该LIB的头文件,如#include "..\lib.h"即可(没有头文件当然就不用了)。

当应用程序对DLL的LIB文件加载后,还需要把DLL对应的头文件(*.h)包含到其中,在这个头文件中给出了DLL中定义的函数原型,然后声明

二, 显式的运行时链接  ,(我用的是此方法) 隐式链接虽然实现较简单,但除了必须的*.dll文件外还需要DLL的*.h文件和*.lib文件,在那些只提供*.dll文件的场合就无法使用,而只能采用显式链接的方式。这种方式通过调用API函数来完成对DLL的加载与卸载,能更加有效地使用内存,在编写大型应用程序时往往采用此方式。这种方法编程具体实现步骤如下: ①使用Windows API函数Load Library或者MFC提供的AfxLoadLibrary将DLL模块映像到进程的内存空间,对DLL模块进行动态加载。 ②使用GetProcAddress函数得到要调用DLL中的函数的指针。 ③不用DLL时,用Free Library函数或者AfxFreeLibrary函数从进程的地址空间显式卸载DLL。 例:在应用程序中调用dll文件

——在应用程序中要首先装入dll后才能调用导出表中的函数,例如用mfc

创建基于对话框的工程test,并在对话框上放置"load"按钮,先添加装载代码。 1.首先在testdlg.cpp的首部添加变量设置代码:

//设置全局变量glibsample用于存储dll句柄

HINSTANCE  glibsample=null  //如果定义成HANDLE类型,则出错

//第二个变量showme是指向dll 库中showme()函数的指针

typedef int(* Showme)(void)

Showme showme

2.利用classwizard为"load"按钮添加装载dll的代码

void ctestdlg::onloadbutton()

{

//要添加的代码如下

if(glibsample!=NULL)

{

AfxMessageBox("the sample.dll has already been load.")

return

}

//装载sample.dll,未加路径,将在三个默认路径中寻找 (1)windows的系统目录:\windows\system

//(2)dos中path所指出的任何目录

//(3)程序所在的目录

glibsample=Loadlibrary("sample.dll")

//返回dll中showme()函数的地址

showme=(Showme)GetProcAddress(glibsample,"showme")

1.lib文件的加载

lib其实就是window下的静态库文件

C++加载静态库文件只能静态加载,在编译的时候进行

下面以vs2010为例:

首先右键单击项目,选择属性:

打开配置属性-链接器-常规-附加库目录

新建一行,填入你要加载lib文件所在的路径

现在设置好了加载的lib目录,再设置要加载的lib

打开项目属性-链接器-输入-附加依赖项

在编辑框输入lib的全名(不带路径)一个文件占一行

现在再编译文件的时候,自动就会使用lib中包含的符号了

2.lib文件的使用

lib文件是window的静态库文件,其实就是很多编译好的函数代码的集合。这种文件里面的代码无法直接执行,必须进行二次编译后才能使用。当你使用了lib中的函数后,编译器会将其代码从lib文件中提取出来,然后追加到你自己的程序中去。所以,使用lib编译出来的执行程序比用dll的大一些,甚至很多。但是这样做,程序的执行效率会高很多(dll必须在运行时去找函数来执行,并且要进行耗时的长跳转),一种典型的通过空间换时间的策略。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11767830.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存