静态库&动态库&导入库
我遇到的问题
先贴一个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 一.什么是库 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执 ...
随机推荐
- Docker快速上手之部署SpringBoot项目
Docker是基于Go语言实现的云开源项目. Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装.分发.部署.运行等生命周期 ...
- QIIME2使用方法
激活qiime2的执行环境:source activate qiime2-2019.4如何查看conda已有的环境:conda info -e 以下分析流程参考:https://docs.qiime2 ...
- FFMPEG学习----分离视频里的H.264与YUV数据
#include <stdio.h> extern "C" { #include "libavcodec/avcodec.h" #include & ...
- c/c++判断文件是否存在
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <fstream> #include <cstd ...
- Go语言实现:【剑指offer】丑数
该题目来源于牛客网<剑指offer>专题. 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7.习惯上我们把1当做是第一个丑 ...
- 【redis】-- redis的持久化(作为数据库)
目录 1.RDB rdb持久化的方式 rdb方式的优点: aof的优点 3.持久化的其他特性 日志重写 工作原理 rdb和aof混合使用 redis是一个基于内存的数据库,故在redis正在运行的数据 ...
- Centos7更改屏幕显示率
第一种,在虚拟机中安装VMwareTools,之后在虚拟机菜单栏"查看"这一项选择立即适应窗口. 第二种,修改/boot/grub2/grub.cfg配置文件,在终端输入su,输入 ...
- awk命令入门
什么是awk? AWK是一个强大的文本处理工具.可以使用awk读取输入文件.为数据排序.处理数据.对输入执行计算以及生成报表,还有无数其他的功能. 使用awk的基本格式 awk [options] ‘ ...
- 通过 python 处理 email - Email via Python
Email via Python 1 MIME - Multipurpose Internet Mail Extensions SMTP - Simple Message Transport Prot ...
- Java Stack使用
1.Stack继承自Vector.遵从先进后出的规则. 2.Stack 是线程同步的.(map.List.Set是线程不同步的,需要在外部封装的时候来同步) 试例代码: public static v ...