我遇到的问题

先贴一个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+格式才需要导入库

静态库&动态库&导入库的更多相关文章

  1. Linux 静态库&动态库调用

    1.什么是库在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于windows和linux的本质不同,因此二者库的二进制是不 ...

  2. windows库的创建和使用:静态库+动态库

    windows库的创建和使用:静态库+动态库   一.静态库的创建和使用 1. 静态库创建 (1)首先创建projecttest,測试代码例如以下: 1) test.h void test_print ...

  3. 生成lua的静态库.动态库.lua.exe和luac.exe

    前些日子准备学习下关于lua coroutine更为强大的功能,然而发现根据lua 5.1.4版本来运行一段代码的话也会导致 "lua: attempt to yield across me ...

  4. C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项

    目录 . 引言 . 交叉编译 . Cygwin简介 . 静态库编译及使用 . 动态库编译及使用 . MinGW简介 . CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件 ...

  5. linux静态与动态库创建及使用实例

    一,gcc基础语法: 基本语法结构:(由以下四部分组成) gcc -o 可执行文件名 依赖文件集(*.c/*.o) 依赖库文件及其头文件集(由-I或-L与-l指明) gcc 依赖文件集(*.c/*.o ...

  6. Linux中创建和使用静态库&动态库

    库本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行 Linux下库的种类 linux下的库有两种:静态库和共享库(动态库). 二者的不同点在于代码被载入的时刻不同. 静态库的代码在 ...

  7. C++开发新版本vs使用旧版本vs编译的静态库动态库

    关于vs潜在的升级问题概述 (Visual C++)查看官网的介绍:潜在的升级问题概述 (Visual C++).主要问题: 1. 如果使用 /GL(全程序优化)进行编译,则生成的对象文件只能使用生成 ...

  8. 静态库动态库的编译、链接, binutils工具集, 代码段\数据段\bss段解释

    #1. 如何使用静态库 制作静态库 (1)gcc *.c -c -I../include得到o文件 (2) ar rcs libMyTest.a *.o 将所有.o文件打包为静态库,r将文件插入静态库 ...

  9. Linux 静态库 & 动态库

    转自:http://blog.chinaunix.net/uid-26833883-id-3219335.html 一.什么是库   本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执 ...

随机推荐

  1. vue计算属性和方法的区别

    计算属性: <div id="example"> <p>{{ now }}"</p> </div> <script& ...

  2. Maven: 互联网开发常用的jar以及版本pom.xl文件

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  3. 《快乐编程大本营》java语言训练班-第4课:java流程控制

    <快乐编程大本营>java语言训练班-第4课:java流程控制 第1节. 顺序执行语句 第2节. 条件分支语句:if条件语句 第3节. 条件分支语句:switch 条件语句 第4节. 条件 ...

  4. 聊聊“装箱”在CLR内部的实现

    原文连接:https://mattwarren.org/2017/08/02/A-look-at-the-internals-of-boxing-in-the-CLR/ 作者 Matt Warren. ...

  5. CNN卷积神经网络入门整合(科普向)

    这是一篇关于CNN入门知识的博客,基本手法是抄.删.改.查,就算是自己的一个笔记吧,以后忘了多看看.   1.边界检测示例假如你有一张如下的图像,你想让计算机搞清楚图像上有什么物体,你可以做的事情是检 ...

  6. Python3(七) 正则表达式与JSON

    一. 初识正则表达式 1.定义:是一个特殊的字符序列,可以帮助检测一个字符串是否与我们所设定的字符序列相匹配. 2.作用:可以实现快速检索文本.实现替换文本的操作. 3.场景: 1.检测一串数字是否是 ...

  7. Docker / Kubernetes 镜像源

    由于众所周知的原因, Docker 官方镜像仓库和 Google 镜像仓库在国内访问速度很慢或者不可用.这样就给我们在部署和使用 Kubernetes 时带来了极大的不便.今天我们就来介绍几种方法,可 ...

  8. 处理异常未知端口 Lsof命令

    需要使用的命令:  ss -tnl 显示所有tcp已被监听的端口  lsof -i:端口 显示所有打开该端口的进程 工作实例: 某天通过ss -tnl发现有不认识的正在被监听的端口 ? 于是使用lso ...

  9. 神奇的 SQL 之 WHERE 条件的提取与应用

    开心一刻 小明:为什么中国人结婚非要选一个好日子呢 ? 楼主:嗯 ? 那肯定啊,结完婚之后你还能有好日子吗 ? 小明:那结婚时所说的白头到老是真的吗 ? 楼主:这哪能是真的,你看现在,头发还没白就秃了 ...

  10. 使用docker创建MySQL容器,并在springboot中使用

    最近在看网上找了个springboot的项目试试,在项目中需要的MySQL版本是5.7,但是本机的MySQL只有5.5.因此想着在我的服务器上跑一个MySQL:5.7的容器解决这一问题,但是在实际操作 ...