dll2lib的简单介绍
如何用VC调用gcc的库
只要有DLL和头文件就行了,但是需要动态调用。
lib文件是静态调用时所需的,由于各个编译器生成的lib文件可能存在格式上的差异,所以最好是不用.LIB。如果你确实要用,但是又没有对应的.LIB文件,你可以用DLL2LIB转,但是效果不敢保证。最可靠的还是这个DLL的提供者给你提供lib。
付动态调用的一段例子,来自MSDN:
#include windows.h
#include stdio.h
typedef int (__cdecl *MYPROC)(LPWSTR);
VOID main(VOID)
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("myputs"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (L"Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message printed from executable\n");
}
如何从DLL中生成LIB文件
Visual C++ 开发工具提供了两个命令行工具,一个是dumpbin.exe,另一个是lib.exe。利用这两个工具即可从dll导出其对应的lib。
1、在命令行执行:
dumpbin /exports yourdll.dll yourdll.def
2、编辑 yourdll.def 文件,使之格式与.def文件格式一致 。比如:
EXPORTS; fn1; fn2;
3、在命令行执行:
lib /def:yourdll.def /machine:i386 /out:yourdll.lib
dll中调用另一个lib
dll中调用的不是另一个lib。DLL调用的不是LIB,而是其他的DLL,LIB只有在编译的时候才有的。呼叫其他的DLL需要注意能够加载到,DLL呼叫的其他的DLL需要放在能够加载到的路径中。
dll库和lib库有什么区别?
关于dll库和lib库的区别如下:
1、使用场景不同:lib是编译时用到的,dll是运行时用到的。
如果要完成源代码的编译,只需要 lib;如果要使动态链接的程序运行起来,只需要dll。
2、用途不同:如果有dll文件,那么lib一般是一些索引信息,记录了dll中函数的入口和位 置,dll中是函数的具体内容;如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。
使用静态编译的lib文件,在运行程序时 不需要再挂动态库,缺点是导致应用程序比较大,而且失去了动态库的灵活性,发布新版本时要发布新的应用程序才可以。
3、应用对象不同:动态链接的情况下,有两个文件:一个是LIB文件,一个是DLL文件。LIB包含被DLL导出的函数名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到DLL 文件。
在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中相应函数代码的地址,从而节省了内存资源。
DLL和LIB文件必须随应用程序 一起发行,否则应用程序会产生错误。如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载。
扩展资料:
dll库和lib库使用方法:
1、使用lib的方法:
静态lib中,一个lib文件实际上是任意个obj文件的集合,obj文件是cpp文件编译生成的。在编译这种静态库工程时,不会遇到链接错误;即使有错,也只会在使用这个lib的EXT文件或者DLL工程里暴露出来。
在VC中新建一个static library类型的工程Lib,加入test.cpp文件和test.h文件(头文件内包括函数声明),然后编译,就生成了Lib.lib文件。
2、使用dll的方法:
使用动态链接中的lib,不是obj文件的集合,即里面不会有实际的实现,它只是提供动态链接到DLL所需要的信息,这种lib可以在编译一个DLL工程时由编译器生成。
参考资料来源:百度百科—lib
参考资料来源:百度百科—dll
如何从动态库DLL生成静态的LIB并使用
在VS中创建一个解决方案,解决方案中包含一个库项目,其余所有的项目依赖这个库项目,并且调用这个库项目中的特定函数
/
LibProject/
UseLibProjectA/
UseLibProjectB/
知识准备
这样的依赖关系可以采用静态依赖库lib和动态依赖库dll实现,博主【技术先生】的一篇博客 1
简明的阐述了两者的区别,这里采用了静态链接库的方式。
操作过程
建立库项目
这里选用 [Visual C++] -[空项目]
修改项目属性,[属性]-[配置属性]-[常规]-[项目默认值]-[配置类型]-[动态库(.dll)]
创建头文件 ?
宏定义部分根据预编译宏来区分编译操作源自dll项目还是使用dll的项目
所有的可能会被外部使用的变量或者方法都需要被[TESTDEPEND_API ]标注出来,博主曾经因为忘记把类默认初始方法标注出来而导致编译失败
#pragma once//TESTDEPEND_EXPORTS 这个宏名称可以自由定义,#ifdef TESTDEPEND_EXPORTS ?#define TESTDEPEND_API __declspec(dllexport) ? #else ?#define TESTDEPEND_API __declspec(dllimport) ? #endif ?#include stringclass A {public: ? ?TESTDEPEND_API A(); ? ?TESTDEPEND_API void hello(std::string name);private : ? ?int c; ? ?int b;
};123456789101112131415161718
生成方法实例
#include "A.h"#include iostreamA::A() : b(1),c(2){}void A::hello(std::string name) { ? ?std::cout b - c "-hello-" name std::endl;}1234567891011
添加编译宏。 [属性]-[配置属性]-[C/C++]-[预编译器]-[预编译器定义] ?添加TESTDEPEND_EXPORTS
至此为止,库项目创建完毕,我们可以直接编译一遍该项目,根据默认配置,会在指定生成路径下生成与项目名称同名的dll和lib 文件。
我们可以采用VS自带的Dumpbin.exe 程序(在VS安装目录可以检索到)检查一下生成的dll文件中的内容,操作参考fengbingchun的博客 ?2 ,这个输出的信息还是很难阅读的,但是导出的方法名和相应的参数名还是可以清晰的推断出来,我们可以人工检查一下输出的方法是否和预期一致。
从其他项目中调用库
这里选用 [Visual C++] -[空项目]
包含头文件, [属性]-[配置属性]-[VC ++目录]-[包含目录] 添加对应文件(.h)的路径,如果可能的话,还是最好添加相对路径,便于迁移
包含库文件路径, [属性]-[配置属性]-[VC ++目录]-[库目录] 添加对应文件(.lib)的路径
添加链接选项, [属性]-[配置属性]-[链接器]-[输入] ?添加对应文件(.lib)的名称 ?e.g TestDepend.lib
这一步是偷懒的操作,这样添加的链接选项会针对每一个需要链接的文件生效,我们可以不配这一步,取而代之,我们在需要链接库文件的地方写下如下预编译选项
#pragma comment (lib,"TestDepend.lib")
在项目中需要的地方调用库文件的内容
//上面是对应的库的头文件名称#include "A.h"//如果不在链接器的输入中添加lib文件名,则需要按下面一行的方式配置//#pragma comment (lib,"TestDepend.lib")int main() { ? ?A a;
? ?a.hello("t1");
? ?a.hello("t2"); ? ?return 0;
}12345678910111213
编译并运行,项目运行成功
在项目发布的时候我们需要将库文件的lib和可执行文件exe放在同级目录,lib文件则不需要了