静态库&动态库&导入库
我遇到的问题
先贴一个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 一.什么是库 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执 ...
随机推荐
- 使用shiro 框架 报错No WebApplicationContext found: no ContextLoaderListener or DispatcherServlet registered?
1.问题描述:ssm 框架中使用shiro 中出现问题 原来web.xml 文件如下: <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, ...
- Java并发专栏
1. Java并发 2. 守护线程与非守护线程 3. 为什么启动线程用start()而不用run()? 4. Java线程join方法总结 5. 生产者与消费者 6. wait.notify/noti ...
- pycharm版本下载地址
https://www.runoob.com/w3cnote/pycharm-windows-install.html 下载社区版本,因为免费 其余按照默认安装即可
- IntelliJ IDEA 2019.3 安装+永久破解[Windows]
IntelliJ IDEA 2019的最后一个版本发布了,听说大幅优化了运行速度,本人实测启动速度确实比以前快不少,所以赶紧安排上新版本IDEA的破解教程 系统环境:Win10 LTSC(1809) ...
- NLP(十九)首次使用BERT的可视化指导
本文(部分内容)翻译自文章A Visual Guide to Using BERT for the First Time,其作者为Jay Alammar,访问网址为:http://jalammar ...
- [兴趣使然]用python在命令行下画jandan像素超载鸡
下午刷煎蛋的时候看到 Dthalo 蛋友发的系列像素超载鸡,就想自己试试用python脚本画一个,老男孩视频里的作业真没兴趣,弄不好吧没意思,往好了写,自己控制不好,能力不够. 所以还是找自己有兴趣的 ...
- WeChall_Training: Programming 1 (Training, Coding)
When you visit this link you receive a message.Submit the same message back to http://www.wechall.ne ...
- Spark作业执行流程源码解析
目录 相关概念 概述 源码解析 作业提交 划分&提交调度阶段 提交任务 执行任务 结果处理 Reference 本文梳理一下Spark作业执行的流程. Spark作业和任务调度系统是其核心,通 ...
- Cacti被监控机器 配置 snmp协议
SNMP(Simple Network Management Protocol,简单网络管理协议)的前身是简单网关监控协议(SGMP),用来对通信线路进行管理. snmpd.conf的 ...
- [Python]Bytes 和 String转换
#----string to bytes------ # 方法一:直接复制bytes类型 b'<str>' b = b'Hello World' print(type(b)) print( ...