`

Linux C++编译及 静态/动态 链接库 笔记

阅读更多
1、C++文件的编译
g++参数介绍(非常棒~)
http://www.cnblogs.com/lidan/archive/2011/05/25/2239517.html
官方文档https://gcc.gnu.org/onlinedocs/
官方参数大全(gcc5.3)https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Option-Summary.html#Option-Summary


-E  预处理, 将#include的文件展开等
-S 生成汇编文件
-c  生成object文件
gcc XX.o  -o XX   链接,,输出文件名为XX

-O1,  -O2,  -O3  优化代码 ,-O3级别最高,   -O1为默认
-g 及   -ggdb  等,,生成调试信息

-fPIC 及 -fpic ,  生成动态链接库时使用,, 前者在多平台通用,但程序运行速度慢

-M ,  -MM,   输出 文件的依赖关系(比如各种.h)文件(写makefile时可以使用)

-std=c++14(或-std=gnu++14)  -std=c++11(或-std=gnu++11)启用 c++14/11的信息,其中使用gnu++14会启用gcc的扩展  :
https://gcc.gnu.org/projects/cxx0x.html
https://gcc.gnu.org/projects/cxx1y.html


一般直接用-c 生成object文件,再多个object文件链接一下即可
或者不指定参数,直接从 多个.cpp 文件生成可执行文件

-Wall  输出尽可能多的警告

-I 头文件路径
-L 库文件路径(静态、动态)
-l 库文件(无需包含扩展名.so 或.a )(但是我自己在Ubuntu14.04.1中直接使用XX.so即可,而不是-lXX.so)



2、静态链接库、动态链接库的编译
Program Library HOWTO:http://www.dwheeler.com/program-library/

C++ dlopen mini HOWTOhttp://www.tldp.org/HOWTO/C++-dlopen/
这篇文章中讲了由于C++的Name Mangling,,需要 extern "C"等封装才能正常使用fopen函数调用C++函数的问题

很多网上的教程会用到 -l 选项指定库文件!!!但是我试的时候直接指定库文件全名就行!!!(具体见makefile内容)


nm  查看exe、.o、.so、 .a文件中的符号信息,比如C++函数名被编译器mangle之后的名称

nm XX.so | c++filt  可以查看函数的原始名称
关于mangling更多请参见http://blog.csdn.net/chenxintao/article/details/7585483

关于库文件搜索路径的问题,没详细实验,在Ubuntu下貌似当前路径也可以~ 这个,用到再试了
只是简单记一下LD_LIBRARY_PATH 的修改方式:http://baike.baidu.com/view/1270749.htm

不多说了,上代码(完整代码见附件):

库文件
#pragma once
int plus(int a,int b);


#include "sharedLib.h"
int plus(int a,int b){
	return a+b;
}


采用静态链接库


采用动态链接库(源文件和采用静态链接库完全相同):


采用动态加载.so文件(fopen)
#include <iostream>
#include <dlfcn.h>  
#include "sharedLib.h"

typedef int (*F)(int,int);
using FF=int (*)(int,int);
int checkDLLState(void* dp){
    const char* dlsym_error= dlerror();
    if (dlsym_error) {
        std::cerr << "Cannot load symbol : " << dlsym_error <<std::endl;
        dlclose(dp);
        return 1;
    }
    return 0;
}

int main(void){
	std::cout<<"Running "<<__FILE__<<std::endl;
	const char* dllName="./sharedLib.so";
    	// reset errors
    	dlerror();
	void* dp=dlopen(dllName, RTLD_LAZY);
	if(checkDLLState(dp))return -1;

	std::cout<<"dp = "<<(unsigned long long)(dp)<<std::endl;
	F f;
	f=(F)( dlsym(dp,"_Z4plusii")); // if do not want to use this name, add extern "C" before the function "plus"
	if(checkDLLState(dp))return -1;
	int sum=f(1,2);
	std::cout<<"The sum is "<<sum<<std::endl<<std::endl;
	dlclose(dp);
}


makefile
看不懂的搜下 “跟我一起写makefile”,,我也是简单学了一下而已
终端内输入  make runall就可以执行程序了
all: main_link_a main_link_so main_dynamicLoad

runall: all
	echo "now beggin running all executations"
	./main_link_a 
	./main_link_so 
	./main_dynamicLoad

#use static library
main_link_a: main_link_a.cpp sharedLib.a
	g++ -Wall -o main_link_a main_link_a.cpp  ./sharedLib.a 

sharedLib.a: sharedLib.cpp sharedLib.h
	g++ -Wall -static -c -o sharedLib.o sharedLib.cpp
	ar rcs sharedLib.a sharedLib.o

#use dynamic library
main_link_so: main_link_so.cpp sharedLib.so
	g++ -Wall -o main_link_so main_link_so.cpp  ./sharedLib.so -ldl

sharedLib.so: sharedLib.cpp sharedLib.h
	g++ -Wall -shared -fPIC -o sharedLib.so sharedLib.cpp

#use fopen,  dynamic load .so libarary, use function by name
main_dynamicLoad: main_dynamicLoad.cpp sharedLib.so
	g++ -Wall -std=c++11 -o main_dynamicLoad main_dynamicLoad.cpp ./sharedLib.so -ldl #-ldl for dynamic link

#view mangled c++ function name in sharedLib.so
viewFuncName: sharedLib.so
	echo viewing mangled function name
	nm sharedLib.so #view mangled function name
	echo 
	echo viewing demangled function name
	nm sharedLib.so | c++filt #view demangled name



clean: 
	-rm *.so *.o *.a #the minus sign at the beginning means the commnand after this one will be executed even error occurs.
	-rm main_link_a main_link_so main_dynamicLoad
	-rm *~


3、设置可执行程序在当前路径下查找.so文件
自己生成了个.so文件,,还得先加到库路径里才能用?
编译可执行文件时只需要添加-rpath=.选项即可!!!!
完整代码为(-WI选项需不需要我没试):
gcc -o test test.c -I. -L. -la -Wl,-rpath=.

引用自:http://blog.csdn.net/cjf_iceking/article/details/25219675
分享到:
评论

相关推荐

    linux qt 动态链接库 静态链接库.docx

    Linux Qt 是一个基于Qt框架的应用程序开发平台,而动态链接库和静态链接库是Linux平台上常用的库链接方式。了解动态链接库和静态链接库的使用是 Qt 开发者必备的技能。 一、动态链接库 动态链接库(Dynamic Link ...

    linux c/c++基础学习资料(百度云链接和提取码)

    同时,理解环境变量、编译链接过程、动态库静态库的使用也是编程环境搭建的关键。此外,学会使用版本控制系统如Git进行代码管理也是现代开发者的必备技能。 然后是C/C++基础知识。C++是C语言的扩展,支持面向对象...

    【cmake实战十】c++从动态库(dll)导出类

    动态库与静态库(.lib)不同,静态库在编译时会被直接合并到目标程序中,而动态库则是在程序运行时动态加载的。DLL可以减少程序的大小,因为多个程序可以共享同一份库的代码。C++从DLL导出类涉及到两个主要步骤:...

    动态链接库DLL学习笔记

    动态链接库(DLL)是Windows操作系统中的一种机制,它允许多个程序共享同一段代码和数据,从而节省内存和磁盘空间。DLL文件包含了可执行代码和数据,而LIB文件则是DLL的导入库,用于静态链接。 在静态链接时,...

    c++学习笔记.pdf

    C++是一种静态类型、编译式、通用的编程语言,它支持过程化...最后,链接阶段将多个目标文件及库文件链接成最终的可执行文件。 以上内容覆盖了C++语言中一些基础知识点,对于学习和理解C++编程具有重要的指导意义。

    达内C/C++笔记

    4. **多线程编程**:利用C++11及更高版本的std::thread和mutex等库进行并发处理。 5. **智能指针**:如std::unique_ptr、std::shared_ptr,用于自动管理对象的生命周期,防止内存泄漏。 6. **Boost库**:提供了许多...

    SQLite开发笔记3(在arm-linux平台上建立嵌入式C数据库)

    成功编译后,在指定的安装路径`/root/sqlite-3.6.5/build/bin`下会生成可执行文件`sqlite3`,在`/root/sqlite-3.6.5/build/include`下生成头文件`sqlite3.h`,在`/root/sqlite-3.6.5/build/lib`下生成静态库`...

    Qt构建动态库静态库.rar

    - 编译静态库时,链接选项应为-Wl,-Bstatic。 4. **测试和调试**: - 构建完成后,通过示例程序测试库功能是否正常。 - 使用调试工具检查链接和运行时错误。 5. **部署**: - 对于动态库,需要将库文件和对应...

    达内学生的C++学习笔记

    9. **预处理器**:预处理器是C++编译过程的一部分,包括宏定义、条件编译等,理解其工作原理有助于编写更高效的代码。 10. **实践项目**:理论学习后,通过编写小程序或参与小型项目,巩固和应用所学知识。 《达内...

    c++笔记.txt

    根据提供的文件信息,可以看出这份文档主要涉及C++中的一些关键概念和知识点,特别是关于静态成员、友元类、以及常量等内容。接下来,我们将详细解释这些知识点。 ### 静态成员 静态成员(包括静态数据成员和静态...

    snmp++-3.3.11a 库相关文件及编译笔记

    1. **环境准备**:安装必要的开发工具,如Visual Studio 2010,确保已配置好C++编译环境。 2. **获取依赖**:SNMP++可能依赖于其他库,如ASN.1编解码库(如berkeley-asn1或openasn1),需要先下载并编译这些依赖库...

    达内嵌入式 Linux开发 笔记

    创建静态库和动态库的过程也有所区别,静态库需要先编译生成目标文件(.o),然后使用ar工具将这些文件打包成库文件(.a)。动态库则需要编译时添加-fpic选项以生成位置无关的代码,然后使用gcc的-shared选项生成.so文件...

    达内C++全程笔记+代码全套分享

    C++是一种静态类型的、编译式的、通用的、大小写敏感的、不仅支持过程化编程,也支持面向对象编程的程序设计语言。它的设计理念是“让程序员能够做出选择”,因此,C++提供了多种编程范式,包括面向对象、泛型编程和...

    达内C++课堂笔记和源码

    3. 静态与动态链接:了解编译时和运行时的链接方式,理解静态库与动态库的区别。 4. 文件I/O:学习使用fstream库进行文件读写操作。 5. 命名空间:避免命名冲突,更好地组织代码。 6. C++11及后续标准的新特性:...

    《C++编程思想》学习笔记

    《C++编程思想》的学习笔记主要涵盖了对象的创建与使用,同时也涉及了语言的翻译过程,包括解释器和编译器的工作原理。本章节详细介绍了C++编程的基础知识,包括编译过程、静态类型检查、分段编译工具的使用,以及...

    c++学习总结,在学习c++时做的一些笔记

    4. **静态与动态绑定**:C++支持静态绑定(编译时绑定)和动态绑定(运行时绑定)。静态绑定发生在编译期间,通常用于非虚函数调用;动态绑定则涉及到虚函数,使得子类可以重写基类的行为。 5. **模板**:模板是C++...

    C++primer笔记

    ### C++ Primer 笔记知识点概述 ...以上是对C++ Primer笔记中涉及的知识点的详细总结,涵盖了文件类型、预处理器指令、注释、数据类型及内存管理等方面的基础知识,对于初学者来说是非常宝贵的学习资源。

    C++学习笔记.chm

    C++是计算机科学中的一种强类型、编译型、静态类型的通用编程语言,由Bjarne Stroustrup在C语言的基础上发展而来,添加了类、模板、命名空间等面向对象特性。C++的学习可以从以下几个方面入手: 1. **基础语法**:...

Global site tag (gtag.js) - Google Analytics