Tags: g++ C++ so library

 

在Linux系统下用g++命令编译C++程序.也可以生成so,a链接库

 

示例一 编译时链接so库

Test.h 文件内容

 

Main.cpp文件内容

 

命令执行过程

 

//生成so文件

g++ -shared -fPIC -o libTestLib.so Test.h

 

//编译Main.cpp并链接so.生成可执行文件Main

g++ Main.cpp -o Main -L.

 

//执行可执行文件Main

./Main

 

 

使用Makefile

 

 

Makefile解读

Makefile的基本规则是

生成目标 : 依赖目标

<TAB>命令

Makefile会首先检查生成目标的依赖目标,若所有依赖目标准备好,则执行下一行以<TAB>(制表符)开头的命令,来产生生成目标.

一般来说一个Makefile只有一个最终目标(一般是Makefile定义的第一个).而这个目标可以依赖其他目标,Makefile会自动检查依赖,并且按依赖关系逐个生成

上面Main目标依赖LibTest.so Main.cpp,其中Main.cpp是源文件,不需要生成,而LibTest.so是一个目标,因此Makefile会找到LibTest.so的生成规则,并首先生成LibTest.so再生成最终目标Main

LibTest.so的生成又依赖于Test.h文件,其中Test.h是源文件,所以可以直接利用下面的<Tab>后的命令生成LibTest.so.因此Makefile首先执行的是g++ -shared -fPIC -o LibTest.so Test.h

在生成LibTest.so后,最终目标Main的所有依赖文件已经准备好,则Makefile执行

g++ Main.cpp -o Main -L.

来生成最终目标Main文件

伪目标

Mainfile中的clean也是一个目标,但是并不依赖于任何文件,这种目标称为伪目标,而且应该用

.PHONY: clean

来声明该伪目标.

Makefile的执行:

对于Makefile的最终目标(一般为第一个),可以直接在命令行执行make命令,由Makefile自动识别来执行

也可以使用

make 目标名

来执行指定目标,而对于伪目标clean,则必须使用 make clean的方式显示执行:

make clean

 

参考

http://blog.csdn.net/haoel/article/details/2887

 

注意:

 

-shared 是指生成动态链接库,详细查Google

http://blog.sina.com.cn/s/blog_54f82cc201011op1.html-fPIC 是指编译代码为可共享,参考:

-o 后面为输出文件名称

-L. 是指的在以下位置查找链接库,其中L后面的(.)是指的是当前目录

 

 

示例二 代码动态加载库

若要动态加载.so库则需要使用dlopen 等函数

目录结构

Test.h内容

extern "C" {

int TestAdd(int x, int y);

}

 

Test.cpp内容

#include "Test.h"

 

extern "C" int TestAdd(int x, int y)

{

return x + y;

}

 

Main.cpp内容

#include <dlfcn.h>

#include <iostream>

using namespace std;

 

int main(int argc, char *argv[])

{

void *handle = dlopen("./Test.so", RTLD_LAZY);

if (!handle)

{

cout << dlerror() << endl;

return -1;

}

typedef int (*add_t)(int a, int b);

add_t add = (add_t) dlsym(handle, "TestAdd");

if (!add)

{

cout << dlerror() << endl;

dlclose(handle);

return -1;

}

int a = add(3,5);

cout << "a = " << a << endl;

dlclose(handle);

return 0;

}

 

Makefile内容:

Main: libTest.so Main.cpp

g++ -ldl -o Main Main.cpp

 

libTest.so: ./Sources/*.cpp

g++ -shared -fPIC -o libTest.so ./Sources/*.cpp -I ./Headers/

 

.PHONY: clean

 

clean:

-rm -f Main

-rm -f libTest.so

 

 

注意:

1.

不管什么库文件,你都既要在包含.h文件(不然编译通不过:有未声明的函数),也要在gcc选项里面指定.so文件的位置(不然链接通不过:未知的符号) 比如 gcc -I include_path -L lib_path -lyourlib include_path改成你头文件的目录 lib_path改成你动态库文件的目录 -lyourlib 改成l加上你要引用的库文件名字 比如libpthread.so就改成-lpthread

http://blog.chinaunix.net/uid-21273878-id-4148042.html

 

 

示例三 Linux下Eclipse 中调用so文件

 

 

首先在Linux下安装Eclipse,确保jdk环境都配置ok

创建Eclipse工程,创建java代码源文件

TestLib.java

public class TestLib {

static{

System.loadLibrary("Test");

}

public static native int TestAdd(int a, int b);

public static void main(String args[])

{

System.out.println(TestAdd(1, 2));

}

}

在TestLib.java文件目录下,使用javac命令生成TestLib.class文件

javac TestLib.java

在bin目录下,找到生成的TestLib.class 文件(若没有该文件,则在TestLib.java相同目录下找,并复制到bin目录下.

在bin目录下,执行以下命令生成C++工程使用的TestLib.h文件

javah -classpath . -jni TestLib

 

生成的TestLib.h

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class TestLib */

 

#ifndef _Included_TestLib

#define _Included_TestLib

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: TestLib

* Method: TestAdd

* Signature: (II)I

*/

JNIEXPORT jint JNICALL Java_TestLib_TestAdd

(JNIEnv *, jclass, jint, jint);

 

#ifdef __cplusplus

}

#endif

#endif

 

创建C++代码Test.cpp,实现TestLib.h中定义的各接口:

Test.cpp

include "TestLib.h"

 

JNIEXPORT jint JNICALL Java_TestLib_TestAdd

(JNIEnv *env, jclass cls, jint a, jint b)

{

return a + b;

}

 

编写Makefile

Makefile 内容

libTest.so: ./Sources/*.cpp

g++ -shared -fPIC -o libTest.so ./Sources/*.cpp -I ./Headers/ \

-I /usr/lib/jvm/java-1.7.0-openjdk.x86_64/include \

-I /usr/lib/jvm/java-1.7.0-openjdk.x86_64/include/linux

 

命令行执行 make libTest.so

生成libTest.so文件,将so文件拖到Eclipse项目中.运行Eclipse项目.

正确调用libTest.so中定义的接口

 

 

注意:

生成的TestLib.h包含了jni.h文件,而且需要jni_md.h文件.所以在g++命令时,需要用 -I 参数指定这两个头文件的路径

 

 

 

 

g++ 生成C++ .so库文件,并调用示例的更多相关文章

  1. 【DSP开发】DSP能用VS2010生成的链接库文件吗?

    [DSP开发]DSP能用VS2010生成的链接库文件吗? 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:可能这个问题让行家看上去就会莞尔一笑,但是很多 ...

  2. 基于FPGA视频时序生成中的库文件

    上一篇分享了一个视频时序生成代码,下面我根据之前项目中用到的时序,对各个参数做了库文件,方便调用. -- -- Package File Template -- -- Purpose: This pa ...

  3. Makefile 自动搜索 c 和 cpp 文件, 并生成 .a 静态库文件

    最近 又弄linux 下的 .a 静态库编译, 于是想 做个 一劳永逸的Makefile, 经过一番折腾, 最后成功了 只需要 改两个 参数 就可以执行了(MYLIB 和 VPATH), 代码 如下: ...

  4. 随机生成数字(ashx文件,调用上篇所写发送邮件代码)

    public void ProcessRequest(HttpContext context) { //邮件标题 string Email_Title = Dsis.Core.SysCore.PubF ...

  5. java调用dll或so动态库文件(c++/c)

    java调用dll或so动态库文件(c++/c) 博客分类:  工作 CC#C++JavaEclipse  java调用dll或so动态库文件(c++/c)开发平台:Eclipse3.3.1.1+CD ...

  6. Makefile学习(二)----生成静态库文件

    Lunix下编译静态库文件: .o后缀文件:编译生成的中间代码文件: .a后缀文件:静态库文件,编译的时候会合到可执行程序中,文件比较大: .so后缀文件:动态库文件,只是一个指向,不会合到可执行程序 ...

  7. 如何实现.so共享库文件

    .so共享库相当于window中的.DLL文件 两个进程同时调用了.so文件,进程就会加载的.so文件到各自的内存空间,而不能实现进程间通讯. .so文件编译的方法: -so文件不需要main文件,即 ...

  8. 从零开始编写动态库文件Makefile,C++版

    这篇文章前,假设你已经看过<跟我一起写Makefile(一)>,陈皓写的那个. 对现有的一个C++动态库文件和调用程序,分别编写Makefile文件,从零开始,花了四天时间才搞清楚一半,生 ...

  9. Android Studio--NDK编译C代码为.so文件,JNI调用

    前言: 从Android Studio开始,就支持jni和.so库调用了. 环境: Windows 7+Android Studio2.1.2+NDK版本:android-ndk-r10e 准备工作: ...

随机推荐

  1. redis修改持久化路径、日志路径、清缓存

    redis修改持久化路径和日志路径 vim redis.conf logfile /data/redis_cache/logs/redis.log #日志路径 dir /data/redis_cach ...

  2. Linux系列之——tomcat 的开机自启动

    --未验证 每次开机都要启动tomcat,非常麻烦:通过直接修改系统文件,实现tomcat自启动: 1. 修改脚本文件rc.local:vim /etc/rc.d/rc.local 这个脚本是使用者自 ...

  3. Linux输出信息并将信息记录到文件(tee命令)

    摘自:https://www.jb51.net/article/104846.htm 前言 最近工作中遇到一个需求,需要将程序的输出写到终端,同时写入文件,通过查找相关的资料,发现可以用 tee 命令 ...

  4. request cluster ID mismatch

    删除了etcd集群所有节点中的--data_dir的内容 [root@node3 ~]# cd /var/lib/etcd/ [root@node3 etcd]# ls member [root@no ...

  5. 123457123456#0#-----com.twoapp.drawGame09--前拼后广--儿童画画游戏jiemei

    com.twoapp.drawGame09--前拼后广--儿童画画游戏jiemei

  6. 【Leetcode_easy】599. Minimum Index Sum of Two Lists

    problem 599. Minimum Index Sum of Two Lists 题意:给出两个字符串数组,找到坐标位置之和最小的相同的字符串. 计算两个的坐标之和,如果与最小坐标和sum相同, ...

  7. 第一次linux下安装nginx记录

    CentOS 7 安装Nginx 并配置自动启动 1.下载Nginx安装包---->地址:http://nginx.org/en/download.html 2.上传安装包到服务期 : rz 命 ...

  8. SpringCloud入门01之基础知识

    一.Spring Cloud 什么是spring cloud, 为什么要使用微服务架构? 参考度娘 Spring Cloud是一系列框架的有序集合, 它利用Spring Boot的开发便利性巧妙地简化 ...

  9. 【计算机视觉】Selective Search for Object Recognition论文阅读2

    Selective Search for Object Recognition 是J.R.R. Uijlings发表在2012 IJCV上的一篇文章.主要介绍了选择性搜索(Selective Sear ...

  10. web 中常用的两种上传文件的方法总结

    这里我们来总结整理一下常用的两种文件上传方式以及要注意的东西: 1.springmvc .MultipartFile 的上传方式. 2.org.apache.commons.fileupload 使用 ...