g++⽣成C++.so库⽂件,并调⽤⽰例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
注意:
-shared 是指⽣成动态链接库,详细查Google
-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
makefile phonyg++ -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
⽰例三 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

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。