静态库&动态库&导入库
我遇到的问题
先贴一个StackOverflow上的问题
上面的问题让我知道了更多动态库的知识。
我需要使用一个声音库(irrKlang)为2d游戏提供声音,我使用的编译器是mingw-w64,但是irrKlang只为windows提供了msvc的动态库,不同编译器产生的库往往不能同时调用,我在链接库时发生了问题。因为不用编译器对c++函数的命名方式不同,msvc命名尤其混乱,导致由于符号不对应无法成功链接。
c库就没有这些蛋疼的问题,由于没有重载啥的,c的函数名就是最后的符号名
我的问题不能通过自己生成导入库解决,因为没法变符号命名约定,像下面这样:
函数声明:
ISoundEngine* createIrrKlangDevice(E_SOUND_OUTPUT_DRIVER driver,int options,const char*,const char*);
gcc的命名方式:
__imp__ZN8irrklang20createIrrKlangDeviceENS_21E_SOUND_OUTPUT_DRIVEREiPKcS2_
msvc的命名方式:
?createIrrKlangDevice@irrklang@@YAPEAVISoundEngine@1@W4E_SOUND_OUTPUT_DRIVER@1@HPEBD1@Z
我的解决思路是直接通过符号查找函数地址:
linux上从库中查找函数需要这些:
#include <dlfcn.h>
void *dlopen(const char *filename, int flag);
char *dlerror(void);
void *dlsym(void *handle, const char *symbol); // 腾讯的libco中就是用这个函数hook了系统调用
int dlclose(void *handle);
windows下:
#include <windows.h>
HMODULE LoadLibrary(LPCSTR lpLibFileName); // LoadLibraryW(Unicode)和LoadLibraryA(ANSI)
FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
BOOL FreeLibrary(HMODULE hLibModule);
我用符号成功找到了函数指针,也成功调用了,但是由于不了解irrklang内部,播放音乐的时候崩了,这个问题解决失败了。
我在StackOverflow上发起了一个提问
静态库(static library)动态库(dynamic library)导入库(import library)
引用一下learncpp.com的相关介绍
A static library (also known as an archive) consists of routines that are compiled and linked directly into your program. When you compile a program that uses a static library, all the functionality of the static library that your program uses becomes part of your executable. On Windows, static libraries typically have a .lib extension, whereas on linux, static libraries typically have an .a (archive) extension. One advantage of static libraries is that you only have to distribute the executable in order for users to run your program. Because the library becomes part of your program, this ensures that the right version of the library is always used with your program. Also, because static libraries become part of your program, you can use them just like functionality you’ve written for your own program. On the downside, because a copy of the library becomes part of every executable that uses it, this can cause a lot of wasted space. Static libraries also can not be upgraded easy -- to update the library, the entire executable needs to be replaced.
A dynamic library (also called a shared library) consists of routines that are loaded into your application at run time. When you compile a program that uses a dynamic library, the library does not become part of your executable -- it remains as a separate unit. On Windows, dynamic libraries typically have a .dll (dynamic link library) extension, whereas on Linux, dynamic libraries typically have a .so (shared object) extension. One advantage of dynamic libraries is that many programs can share one copy, which saves space. Perhaps a bigger advantage is that the dynamic library can be upgraded to a newer version without replacing all of the executables that use it.
Because dynamic libraries are not linked into your program, programs using dynamic libraries must explicitly load and interface with the dynamic library. This mechanism can be confusing, and makes interfacing with a dynamic library awkward. To make dynamic libraries easier to use, an import library can be used.
An import library is a library that automates the process of loading and using a dynamic library. On Windows, this is typically done via a small static library (.lib) of the same name as the dynamic library (.dll). The static library is linked into the program at compile time, and then the functionality of the dynamic library can effectively be used as if it were a static library. On Linux, the shared object (.so) file doubles as both a dynamic library and an import library. Most linkers can build an import library for a dynamic library when the dynamic library is created.
静态库:后缀名win:.lib linux:.a, 直接链接到程序中
动态库:后缀名win:.dll linux:.so, 不会成为可执行文件的一部分。两种加载方式:1.隐式加载:将导入库想静态库一样链接 2.通过系统提供的api运行时加载
导入库:后缀名win:.lib, 使加载和使用动态库的过程自动化。linux上.so文件既是动态库又是导入库。导入库中不含代码,而是为链接程序提供信息,包含建立动态链接时要用到的重定位表。
使用mingw-w64的工具为动态链接库生成导入库
windows的.dll(msvc生成的)通常不能直接链接到gcc编译的程序,要为它生成导入库
> gendef.exe foo.dll # 生成导出定义,这个文件包含导出的函数符号
> dlltool.exe --dllname foo.dll --input-def foo.def --output-lib libfoo.lib # 生成导入库
# 只有msvs也就是win的动态库需要生成导入库,对gcc生成的动态库执行会失败
> gendef.exe glfw3.dll
* [glfw3.dll] Found PE+ image
* failed to create glfw3.def ...
# 猜测 pe+ 格式的动态库可能包含导入库(想linux的.so一样), 只有不是pe+格式才需要导入库
静态库&动态库&导入库的更多相关文章
- Linux 静态库&动态库调用
1.什么是库在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于windows和linux的本质不同,因此二者库的二进制是不 ...
- windows库的创建和使用:静态库+动态库
windows库的创建和使用:静态库+动态库 一.静态库的创建和使用 1. 静态库创建 (1)首先创建projecttest,測试代码例如以下: 1) test.h void test_print ...
- 生成lua的静态库.动态库.lua.exe和luac.exe
前些日子准备学习下关于lua coroutine更为强大的功能,然而发现根据lua 5.1.4版本来运行一段代码的话也会导致 "lua: attempt to yield across me ...
- C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项
目录 . 引言 . 交叉编译 . Cygwin简介 . 静态库编译及使用 . 动态库编译及使用 . MinGW简介 . CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件 ...
- linux静态与动态库创建及使用实例
一,gcc基础语法: 基本语法结构:(由以下四部分组成) gcc -o 可执行文件名 依赖文件集(*.c/*.o) 依赖库文件及其头文件集(由-I或-L与-l指明) gcc 依赖文件集(*.c/*.o ...
- Linux中创建和使用静态库&动态库
库本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行 Linux下库的种类 linux下的库有两种:静态库和共享库(动态库). 二者的不同点在于代码被载入的时刻不同. 静态库的代码在 ...
- C++开发新版本vs使用旧版本vs编译的静态库动态库
关于vs潜在的升级问题概述 (Visual C++)查看官网的介绍:潜在的升级问题概述 (Visual C++).主要问题: 1. 如果使用 /GL(全程序优化)进行编译,则生成的对象文件只能使用生成 ...
- 静态库动态库的编译、链接, binutils工具集, 代码段\数据段\bss段解释
#1. 如何使用静态库 制作静态库 (1)gcc *.c -c -I../include得到o文件 (2) ar rcs libMyTest.a *.o 将所有.o文件打包为静态库,r将文件插入静态库 ...
- Linux 静态库 & 动态库
转自:http://blog.chinaunix.net/uid-26833883-id-3219335.html 一.什么是库 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执 ...
随机推荐
- alert弹出窗口,点击确认后关闭页面
alert("点击确认后,关闭页面"); window.opener=null;window.top.open('','_self','');window.close(this);
- CentOS 7 上CNVnator安装
1.到github上下载最新版本 https://github.com/abyzovlab/CNVnator/releases 2.先看INSTALL文件,要求以下依赖,我的机器上已经安装了前两个,所 ...
- 对result文件进行数据清洗以及进行可视化
项目源码地址:https://github.com/gayu121/result(项目里操作的数据都是清洗过后的数据) 测试要求: 1. 数据清洗:按照进行数据清洗,并将清洗后的数据导入hive数据库 ...
- WTL对话框添加背景图片
WTL91_5321_Final + VS2013 + WIN7 // MainDlg.h : interface of the CMainDlg class // ///////////////// ...
- Bash 脚本中的 set -euxo pipefail
有些开发人员会用Bash来实现很复杂的功能,就像使用别的高级语言一样.他可能觉得自己很牛逼但其他人早就想锤爆他了,Bash的可读性和可维护性远远低于任何高级语言.更要命的是,Bash并没有方便的调试工 ...
- Codeforces_814
A.b序列从大到小填a序列中的0,在判断. #include<bits/stdc++.h> using namespace std; ],b[]; int main() { ios::sy ...
- dosbox,masm的挂载
masm文件夹下 1 asm文件夹用来存储asm文件 2 几个masm的应用程序 3 masm 生成的Obj文件和Link生成的exe文件 在dosbox目录下修改option文件加入 这样开始dos ...
- Dapper系列 作者:懒懒的程序员一枚
Dapper 第一篇简单介绍什么是小巧玲珑?Dapper如何工作安装需求方法参数结果常用类型 Dapper 第二篇 Execute 方法介绍描述存储过程Insert语句Update语句Delete语句 ...
- 原生servlet项目启动自动加载一个方法
web.xml里的配置: 配置好要加载的类,其中1这一句是项目启动时自动加载该类的必要条件. <servlet> <servlet-name>SharePltfCLServle ...
- CAS 分析
CAS是什么 (1) CAS(Compare and Swap) 比较并交换, 比较并交换是在多线程并发时用到的一种技术 (2) CAS是原子操作, 保证并发安全性, 而不是保证并发同步. (3) C ...