静态库&动态库&导入库
我遇到的问题
先贴一个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 一.什么是库 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执 ...
随机推荐
- JDK源码之Byte类分析
一 简介 byte,即字节,由8位的二进制组成.在Java中,byte类型的数据是8位带符号的二进制数,以二进制补码表示的整数 取值范围:默认值为0,最小值为-128(-2^7);最大值是127(2^ ...
- flask使用blinker信号机制解耦业务代码解决ImportError: cannot import name 'app',以异步发送邮件为例
百度了大半天,不知道怎么搞,直到学习了blinker才想到解决办法,因为之前写java都是文件分开的, 所以发送邮件业务代码也放到view里面,但是异步线程需要使用app,蛋疼的是其他模块不能从app ...
- js的new操作符深度解析
引言 我们都知道new操作符在js中一般是用来创建一个构造函数的实例,它在创建实例具体做了什么,MDN文档是这么说的: 我一开始看到,完全没有任何的头绪和理解,到底什么意思,后面通过上网查阅了大量的资 ...
- (数据科学学习手札74)基于geopandas的空间数据分析——数据结构篇
本文对应代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 geopandas是建立在GEOS.GDAL.P ...
- PE可执行文件加载器
PE文件加载器 模仿操作系统,加载pe文件到内存中 该项目主要是为了检测pe的学习程度,是否都完全理解了.当然没有完全理解 实现功能的如下: 模仿操作系统,加载pe文件到内存中,然后执行待执行的pe文 ...
- MQTT协议的学习
MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议.它的设计思想是轻巧.开放.简单.规范,易于实现.这些特点使得它对很多场景来说都是很好的选择,特别是对于受限的环境如机器与机器的通信(M2M ...
- 你都这么拼了,面试官TM怎么还是无动于衷
面试,对于每个人而然并不陌生,可以说是必须经历的一个过程了,小到一场考试,大到企业面试,甚至大型选秀...... 有时自己明明很努力了,但偏偏会在面试环节出了插曲,比如,紧张就是最容易出现的了. 我相 ...
- Python爬虫小结
有些数据是没有专门的数据集的,为了找到神经网络训练的数据,自然而然的想到了用爬虫的方法开始采集数据.一开始采用了网上的一个动态爬虫的代码,发现爬取的图片大多是重复的,有效图片很少. 动态爬虫: fro ...
- centos7 手把手从零搭建深度学习环境 (以TensorFlow2.0为例)
目录 一. 搭建一套自己的深度学习平台 二. 安装系统 三. 安装NVIDA组件 四. 安装深度学习框架 TensorFlow 五. 配置远程访问 六. 验收 七. 福利(救命稻草
- MongoDB、Redis和Memcached介绍
MongoDB MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非 ...