Java通过swig调用C++接口

| 2015年9月10日

记录一下过程

c++代码: swigshape.h

#ifndef TEST_CODE_SWIG_TEST_SHAPE_H
#define TEST_CODE_SWIG_TEST_SHAPE_H
#pragma once

class Shape {
public:
Shape() {
nshapes++;
}
virtual ~Shape() {
nshapes--;
};
double x, y;
void move(double dx, double dy);
virtual double area() = 0;
virtual double perimeter() = 0;
int nshapes;
};

class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) { };
~Circle() {};
virtual double area();
virtual double perimeter();
};

class Square : public Shape {
private:
double width;
public:
Square(double w) : width(w) { };
~Square() {};
virtual double area();
virtual double perimeter();
};

#endif // TEST_CODE_SWIG_TEST_SHAPE_H

swig代码:swigshape.i

/* File : swigshape.i */
%module swigshape

%{
#include "swigshape.h"
%}

/* Let's just grab the original header file here */
%include "swigshape.h"

java测试代码: helloswig.java

public class helloswig {

static {
System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("shape");
}

public static void main(String argv[]) {
//
System.out.println( "Creating some objects:" );
Circle c = new Circle(10);
System.out.println( " Created circle " + c );
Square s = new Square(10);
System.out.println( " Created square " + s );

c.delete();
s.delete();

System.out.println( "Goodbye" );
}
}

scons文件:SConstruct

VariantDir(".obj/", "./", duplicate=0);
env = Environment() # Initialize the environment
env.Append(CCFLAGS = ['-g','-O3'])

env.Append(CPPDEFINES={'RELEASE_BUILD' : '1'})
env.Append(LIBPATH = ['/usr/local/lib/'])
env.Append(CPPDEFINES=['BIG_ENDIAN'])
env.Append(CPPPATH = ['/usr/local/include/', '/usr/lib/jvm/java-8-openjdk-amd64/include/', '/usr/lib/jvm/java-8-openjdk-amd64/include/linux/'])


env.SharedLibrary(
target = 'shape',
source = [".obj/swigshape.cpp", ".obj/swigshape_wrap.cxx"]
)

swigshape_wrap.cxx 由swig编译生成

编译运行:

elight@helight-xu:/data/helight_project/xlight/test_code/swig_test$ swig -c++ -java swigshape.i

helight@helight-xu:/data/helight_project/xlight/test_code/swig_test$ ls
Circle.java helloswig.java SConstruct Shape.java Square.java swigshape.cpp swigshape.h swigshape.i swigshape.java swigshapeJNI.java swigshape_wrap.cxx

编译生成静态库:

helight@helight-xu:/data/helight_project/xlight/test_code/swig_test$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: .obj
g++ -o libshape.so -shared .obj/swigshape.os .obj/swigshape_wrap.os -L/usr/local/lib
scons: done building targets.
helight@helight-xu:/data/helight_project/xlight/test_code/swig_test$ ls
Circle.java helloswig.java libshape.so SConstruct Shape.java Square.java swigshape.cpp swigshape.h swigshape.i swigshape.java swigshapeJNI.java swigshape_wrap.cxx

编译java代码:

helight@helight-xu:/data/helight_project/xlight/test_code/swig_test$ javac *.java
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar

运行代码:

helight@helight-xu:/data/helight_project/xlight/test_code/swig_test$ export LD_LIBRARY_PATH=./
helight@helight-xu:/data/helight_project/xlight/test_code/swig_test$ java helloswig
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar
./:/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib
Creating some objects:
Created circle Circle@677327b6
Created square Square@14ae5a5
Goodbye
helight@helight-xu:/data/helight_project/xlight/test_code/swig_test$

编译问题:

helight@helight-xu:/data/helight_project/xlight/test_code/swig_test$ java helloswig
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar
Exception in thread "main" java.lang.UnsatisfiedLinkError: no shape in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at helloswig.<clinit>(helloswig.java:4)

主要是jvm运行时候加载我们指定的shape的动态库的时候找不到路径,用下买的方式增加一个搜索目录.

export LD_LIBRARY_PATH=./

helight@helight-xu:/data/helight_project/xlight/test_code/swig_test$ java helloswig
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar
./:/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib
Creating some objects:
Exception in thread "main" java.lang.UnsatisfiedLinkError: shapeJNI.new_Circle(D)J
at shapeJNI.new_Circle(Native Method)
at Circle.<init>(Circle.java:38)
at helloswig.main(helloswig.java:11)

主要静态库编译的时候没有swig的文件也编译到里面导致,在scons的配置文件中增加:swigshape_wrap.cxx

g++ -o .obj/shape_wrap.os -c -g -O3 -fPIC -DRELEASE_BUILD=1 -DBIG_ENDIAN -I/usr/local/include shape_wrap.cxx
shape_wrap.cxx:159:17: fatal error: jni.h: No such file or directory
#include <jni.h>

java的jni头文件引用路径没有设置, 以下方式添加.

env.Append(CPPPATH = ['/usr/local/include/', '/usr/lib/jvm/java-8-openjdk-amd64/include/', '/usr/lib/jvm/java-8-openjdk-amd64/include/linux/'])
看完本文有收获?请分享给更多人

关注「黑光技术」,关注大数据+微服务