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. ios排序NSArray(数字.字符串)

    NSArray *originalArray = @[@"1",@"21",@"12",@"11",@"0&q ...

  2. 123457123456---熊猫宝贝连数字游戏(儿童连数字)--com.threeObj03.shuziLink

    熊猫宝贝连数字游戏(儿童连数字)--com.threeObj03.shuziLink

  3. python中os.popen, os.system()区别

    直接上个例子吧,注意结果,os.system的结果只是命令执行结果的返回值,执行成功为0: >>> a=os.system('ls') Applications Movies pyt ...

  4. 【产品】C转B

    http://www.woshipm.com/pmd/2780830.html 这篇文章总结的不错.

  5. (2) Java SQL框架(java.sql.*)中常用接口详解

    Driver接口:定义了一个驱动程序接口,每一个数据库的JDBC driver都应该实现这个接口,用于访问对应的数据库.比如MySQL的driver为com.mysql.jdbc.Driver.Jav ...

  6. 【Leetcode_easy】693. Binary Number with Alternating Bits

    problem 693. Binary Number with Alternating Bits solution1: class Solution { public: bool hasAlterna ...

  7. iOS技术面试05:UI控件

    怎么解决缓存池满的问题 1> 优先移除使用次数比较少的对象 2> 优先移除缓存时间最长的对象(让年轻的活下来) 3> 优先移除占用内存比较大的对象 CAAnimation的层级结构 ...

  8. 35个高级Python知识点总结

    原文地址:https://blog.51cto.com/xvjunjie/2156525 No.1 一切皆对象 众所周知,Java中强调“一切皆对象”,但是Python中的面向对象比Java更加彻底, ...

  9. php 阿里云国内短信实例

    调用:先去阿里云申请短信服务 $smsArr = array( "accessKeyId" => "", // key "accessKeySe ...

  10. 使用自定义Comparator对TreeSet中的数据进行多条件排序

    代码记录(需求:根据店铺等级和店铺到某个点的距离进行排序,其中店铺等级由高到低,距离由近及远) 需要排序的对象Store,Store.java package com.zhipengs.work.te ...