A. 我在一个机器上编了个动态库,在另一个机器上编译了一个引用这个动态库的可执行程序,能调用不
什么语言?C++还是C#?Native还是managed?
一般是没有问题的,只要保证:
1、你这个动态库没有依赖其他动态库(包括系统的、MFC的、CRT的、VC的、或者.NET Framework的),或者依赖的其他动态库在另一台机器上也都有;
2、而且不存在32位和64位的兼容问题(即动态库以及可执行程序都是32位的或者都是64位的,而且操作系统也不存在这个兼容性的差异);
3、可执行程序连接动态库使用的LIB文件和动态库是匹配的(如果是native的)
____________________
补充:
哦~~~ linux我是门外汉了,那就看看其他朋友有没有Linux大拿帮忙回答一下吧……
B. VC程序调用动态库,编译时候也跟着编译动态库
不太清楚你的工程是如何建立的,想必一个工程是生成动态链接库,另一个是调用程序EXE了。由于VC动态库有两种形式,Regular和Extended两种,其中一种能导出类,另一种只能导出变量和函数。如果导出的是类,你在编译EXE文件时自然需要用到类得声明文件,即你前面所说的动态库本身所引用的文件。如果导出的是函数或变量,有可能出现的情况是:一般为了代码的重用性,把需要导出的函数或变量单独放在一个头文件中,用一个宏控制其导入、导出。编译动态库时,宏定义为导出,编译EXE时,宏变为导入,这个头文件为两者共用。如果不小心在这个头文件中包含了其他头文件,也可能出现你说的情况。如果动态库调用直接采用函数入口地址的方法,则什么都不用声明,当然,只适用于导出函数与变量的情形。
C. 怎样使用动态库中的条件编译
publicstaticvoidabc(){#region要执行的代码stringstrCode=@"usingSystem;usingSystem.Text;usingSystem.Collections.Generic;usingSystem.Linq;namespaceaaa{publicclassbbb{publicstaticstringccc(stringname){return""abc"";}}}";#endregion#region编译参数=newCompilerParameters();objCompilerParams.GenerateExecutable=false;//编译成exe还是dllobjCompilerParams.GenerateInMemory=false;//是否写入内存,不写入内存就写入磁盘objCompilerParams.OutputAssembly="E:\abc.dll";//输出路径objCompilerParams.IncludeDebugInformation=false;//是否产生pdb调试文件默认是falseobjCompilerParams.ReferencedAssemblies.Add("System.dll");objCompilerParams.ReferencedAssemblies.Add("System.Core.dll");//编译器选项:编译成(存储在内存中)的DLL/*objCompilerParams.CompilerOptions="/target:library/optimize";//编译时在内存输出objCompilerParams.GenerateInMemory=true;//不生成调试信息objCompilerParams.IncludeDebugInformation=false;*/#endregion#region编译//创建编译类CSharpCodeProviderobjCompiler=newCSharpCodeProvider();//进行编译=objCompiler.CompileAssemblyFromSource(objCompilerParams,strCode);#endregion#region取得编译成程序集,准备执行程序集里的类中的方法//获取编译结果:程序集AssemblyobjAssembly=objCompileResults.CompiledAssembly;//获取编译成的程序集的信息/*objectobjMainClassInstance=objAssembly.CreateInstance("Program");TypeobjMainClassType=objMainClassInstance.GetType();*/#endregion#region调用程序集中的类,执行类中的方法,得到结果/*objMainClassType.GetMethod("Main").Invoke(objMainClassInstance,null);objMainClassType.GetMethod("PrintWorld").Invoke(objMainClassInstance,null);*/#endregion
D. 动态库链接编译
这里的动态的意思应该是模块代码是动态加载的
而不是随着应用程序一起编译
只要动态库里的函数接口不变
应用程序就无需重新编译
只需将动态库重新编译后替换掉旧的动态库即可
如果动态库的函数接口有变动
那么应用程序就要重新编译发布
这也是我的个人理解~~~
E. C++中动态库调用动态库如何调用啊
动态连接库的创建步骤:
一、创建Non-MFC DLL动态链接库
1、打开File —> New —> Project选项,选择Win32 Dynamic-Link Library —>sample project—>工程名:DllDemo
2、新建一个.h文件DllDemo.h
以下是引用片段:
#ifdefDllDemo_EXPORTS
#defineDllAPI__declspec(dllexport)
#else
#defineDllAPI__declspec(dllimport)
extern"C"//原样编译
{
DllAPIint__stdcallMax(inta,intb);//__stdcall使非C/C++语言内能够调用API
}
#endif
3、在DllDemo.cpp文件中导入DllDemo.h文件,并实现Max(int,int)函数,以下是引用片段:
#include"DllDemo.h"
DllAPIint__stdcallMax(inta,intb)
{
if(a==b)
returnNULL;
elseif(a>b)
returna;
else
returnb;
}
4、编译程序生成动态连接库
二、用.def文件创建动态连接库DllDemo.dll。
1、删除DllDemo工程中的DllDemo.h文件。
2、在DllDemo.cpp文件头,删除 #include DllDemo.h语句。
3、向该工程中加入一个文本文件,命名为DllDemo.def并写入如下语句:
LIBRARY MyDll
EXPORTS
Max@1
4、编译程序生成动态连接库。
动态链接的调用步骤:
一、隐式调用
1、 建立DllCnslTest工程
2、 将文件DllDemo.dll、DllDemo.lib拷贝到DllCnslTest工程所在的目录
3、 在DllCnslTest.h中添加如下语句:
以下是引用片段:
#defineDllAPI__declspec(dllimport)
#pragmacomment(lib,"DllDemo.lib")//在编辑器link时,链接到DllDemo.lib文件
extern"C"
{
DllAPIint__stdcallMax(inta,intb);
}
4、在DllCnslTest.cpp文件中添加如下语句,以下是引用片段:
#include"DllCnslTest.h"//或者#include"DllDemo.h"
voidmain()
{
intvalue;
value=Max(2,9);
printf("TheMaxvalueis%d
",value);
}
5、编译并生成应用程序DllCnslTest.exe
二、显式调用
1、 建立DllWinTest工程
2、 将文件DllDemo.dll拷贝到DllWinTest工程所在的目录或Windows系统目录下。
3、 用vc/bin下的Dumpbin.exe的小程序,查看DLL文件(DllDemo.dll)中的函数结构。
4、 使用类型定义关键字typedef,定义指向和DLL中相同的函数原型指针。
例:
以下是引用片段:
typedefint(*lpMax)(inta,intb);//此语句可以放在.h文件中
5、 通过LoadLibray()将DLL加载到当前的应用程序中并返回当前DLL文件的句柄。
例:
以下是引用片段:
HINSTANCEhDll;//声明一个Dll实例文件句柄
hDll=LoadLibrary("DllDemo.dll");//导入DllDemo.dll动态连接库
6、 通过GetProcAddress()函数获取导入到应用程序中的函数指针。
例:
以下是引用片段:
lpMaxMax;
Max=(lpMax)GetProcAddress(hDLL,"Max");
intvalue;
value=Max(2,9);
printf("TheMaxvalueis%d",value);
7、 函数调用完毕后,使用FreeLibrary()卸载DLL文件。
FreeLibrary(hDll);
8、 编译并生成应用程序DllWinTest.exe
F. 如何让自己的程序动态引用debug和release的库
本文所描述的动态库是基于MFC的。IDE是VS2005. 默认情况下,如果一个动态库工程名叫A,动态库的名称将是A.lib A.dll A.def。不管工程是release下还是debug下。这就导致一个问题。如果我在另一个工程中使用这个动态库,这个工程在release下应该链接release下的相应库文件,这个工程在debug下应该链接debug下的相应库文件。于是乎,可能需要来回拷贝覆盖。甚是麻烦。为什么我们的动态库工程不能像OpenCV那样,debug就将默认生成的库名由默认的A.lib A.dll换成Ad.lib和Ad.dll呢?如果这能实现,我们在使用这些库的工程中的"项目"->"属性"->"链接器"->"输入"->"附加依赖库"里面分别设置不就OK了吗。 修改动态库名称的方法如下:(1) 打开动态库工程,设置DEBUG模式,然后选择"项目"->"属性"->"链接器"->"常规"->"输出文件",一般在文件名后附加 'd'即可。(2) 选择"项目"->"属性"->"链接器"->"高级"->"导入库",一般在文件名后附加 'd'即可。(3) 选择"项目"->"属性"->"链接器"->"输入"->"模块定义文件",一般在文件名后附加 'd'即可。注意:这里是需要一个模块定义文件,工程下默认只有 "工程名.def" 文件,需要将该文件复制一份,然后修改其中LIBRARY 后面引号中的内容加一个d。如; ListCtrlEx.def : Declares the mole parameters for the DLL.LIBRARY "ListCtrlEx" DESCRIPTION 'ListCtrlEx Windows Dynamic Link Library'EXPORTS ; Explicit exports can go here 修改后为:; ListCtrlEx.def : Declares the mole parameters for the DLL.LIBRARY "ListCtrlExd" ; Explicit exports can go here 如果不做这一步,在编译动态库时会出现如下警告 (4) release的个人认为无需改变。这样选择菜单"生成"->"批生成"生成debug和release版本的库。 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 到这里我们大概完成了任务的80%。接下来就像使用很多开源软件包一样,设置我们自己的工程。(1) 选择"项目"->"选项"->"项目和解决方案"->"C++目录",选择库文件,然后将刚刚生成的debug和release版本的库的路径填入。
G. 如何确定程序调用了动态库或者静态库
可以得出第一个结论:都为静态链接库,有同名函数参与情况下,链接会出现符号多次定义的错误!
两个动态库
再来看看动态链接库,同样的libA libB 生成动态链接库
测试主程序不修改 ! 还是为:
这种编译方式叫做动态库的隐式调用, 如果你删除一个libA.so , 运行a.out 会出现不能找到动态库的错误.
这种情况也可以称为 加载时链接! 静态库属于编译时链接!
可以得出第二个结论: 若都为动态库,并且进行隐式调用,输出结果和动态库的顺序有关.
再继续看看动态加载动态库.
修改测试主程序
同样可以得出结论,动态链接库如果不加库连选项 ,函数调用是正确的 加库路径,会以库的路径顺序为主! 左边覆盖右边. 而且当只链接其中一个时 也生效
H. linux 编译怎么连接动态库
Linux的动态库文件是以lib字样开头的.so文件,编译链接动态库有两个要点:一个是需要用-L选项指定动态库的搜索路径,这个搜索路径是需要连接的so文件的大致路径,比如/usr/openssl/lib;另外还需要用-l(这个是小写的L)选项指定动态库的名字,比如下面这条编译命令:
gcc -o hello hello.c -L/usr/openssl/lib -lcrypto
I. unix 下的C++编程在编译时怎么链接动态库第二个问题 在程序中怎么调用
你说的是手动显示调用,不是静态隐式调用。
#include<dlfcn.h>
此头文件在编译时需要加入 -ldl选项
动态链接库 必须加入:-fpic选项。
------
void *dll=NULL;//保存动态链接库的句柄。
int (*dll_fun)(char*)=NULL;//想要调用的函数指针。
dll=dlopen("/lib/XXX.so", RTLD_NOW)//打开so文件。
dll_fun=dlsym(dll,"my_print");//获取指定函数的指针。
dll_fun("Call my_print");
dlclose(dll)
---
编译链接有两种方法,
1. 使用-lXX 选项,gcc会自动在库路径中链接libXX.so的文件 gcc main.c -lstdc++ -omain
2. 在命令行中将库路径作为参数传入。 gcc main.c /lib/libstdc++.so -omain