%%writefile foo.cpp #include // A simple class with a constuctor and some methods... // 생성자와 몇 개의 메소드를 가지는 간단한 클래스... class Foo { public: Foo(int); void bar(); int foobar(int); private: int val; }; Foo::Foo(int n) { val = n; } void Foo::bar() { std::cout << "Value is " << val << std::endl; } int Foo::foobar(int n) { return val + n; } add_src = """ extern "C" { Foo* Foo_new(int n) {return new Foo(n);} void Foo_bar(Foo* foo) {foo->bar();} int Foo_foobar(Foo* foo, int n) {return foo->foobar(n);} }""" f = open('foo.cpp', 'a') f.write(add_src) f.close() !g++ -c -fPIC foo.cpp -o foo.o !g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o !ls -lrt !cat foo.cpp %%writefile foo.py import ctypes lib = ctypes.cdll.LoadLibrary('./libfoo.so') class Foo(object): def __init__(self, val): lib.Foo_new.argtypes = [ctypes.c_int] lib.Foo_new.restype = ctypes.c_void_p lib.Foo_bar.argtypes = [ctypes.c_void_p] lib.Foo_bar.restype = ctypes.c_void_p lib.Foo_foobar.argtypes = [ctypes.c_void_p, ctypes.c_int] lib.Foo_foobar.restype = ctypes.c_int self.obj = lib.Foo_new(val) def bar(self): lib.Foo_bar(self.obj) def foobar(self, val): return lib.Foo_foobar(self.obj, val) !python !apt-get update !apt-get install openjdk-8-jdk-headless -qq > /dev/null import os os.environ["JAVA_HOME"] = "/usr/lib/jvm/java-8-openjdk-amd64" os.environ["PATH"] = "/usr/lib/jvm/java-8-openjdk-amd64/bin:" + os.environ["PATH"] !java -version !wget https://services.gradle.org/distributions/gradle-3.4.1-bin.zip -P /tmp !sudo unzip -d /opt/gradle /tmp/gradle-*.zip import os os.environ["GRADLE_HOME"] = "/opt/gradle/gradle-3.4.1" os.environ["PATH"] = "/opt/gradle/gradle-3.4.1/bin:" + os.environ["PATH"] !gradle -v %%writefile build.gradle // Java 프로그램을 위한 기능을 제공하는 플러그인 apply plugin: 'java' // apply plugin: 'com.github.johnrengelman.shadow' // gradle 스크립트에서 외부 라이브러리를 참 buildscript { // JCenter라는 저장소. Maven과 Gradle 등 각종 빌드 도구에서 사용할 수 있는 공개 저장소 repositories { jcenter() } // 의존 라이브러리. fat-jar를 만들기 위해 shadowJar라는 라이브러리 사용. dependencies { classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.1' } } // 저장소 설정 repositories { // Apache Maven 중앙 저장소를 이용하기 위한 것 mavenCentral() } // 의존 라이브러리. dependencies { // 컴파일시 의존 라이브러리. JNA 라이브러리 4.1을 추가로 사용해야 함. compile 'net.java.dev.jna:jna:4.1.0' compile 'net.java.dev.jna:jna-platform:4.1.0' } // jar task가 실행될 때 마다 shadowJar가 실행되게 하려면, 아래처럼 jar에 finalizedBy를 달아주면 된다. jar { finalizedBy shadowJar // jar 파일을 만드려면 manifest 파일 정보가 필요함. // main class는 hello 패키지에 Foo 클래스임. manifest { attributes 'Main-Class': 'hello.Foo', 'Implementation-Title': 'Foo jna Project', 'Implementation-Version': '1.0' } } !mkdir -p src/main/java/hello %%writefile src/main/java/hello/Foo.java package hello; import com.sun.jna.Native; import com.sun.jna.Platform; import com.sun.jna.Library; import com.sun.jna.Pointer; public class Foo { public interface FooLib extends Library { Pointer Foo_new(int n); void Foo_bar(Pointer foo); int Foo_foobar(Pointer foo, int n); } private String sopath; private FooLib INSTANCE; private Pointer self; private void loadLibrary(int n) { INSTANCE = (FooLib)Native.loadLibrary( sopath, FooLib.class ); self = INSTANCE.Foo_new(n); } public Foo(int n) { sopath = "libfoo.so"; loadLibrary(n); } public Foo(String sopath, int n) { this.sopath = sopath; loadLibrary(n); } public void bar() { INSTANCE.Foo_bar(self); } public int foobar(int n) { return INSTANCE.Foo_foobar(self, n); } public static void main(String[] args) { String path = System.getProperty("user.dir") + "/libfoo.so"; //String path = "/content/libfoo.so"; System.out.println(path); Foo f = new Foo(path,5); f.bar(); System.out.println("f.foobar(7) = " + f.foobar(7)); int x = f.foobar(2); System.out.println("x = " + x); } } !gradle build !ls -lrt build/libs/*.jar !java -jar build/libs/content-all.jar %%writefile Makefile SRCS = foo.cpp OBJS = foo.o CFLAGS = $(CFLAG) -D_REENTRANT -D_THREAD_SAFE -D$(_OSTYPE_) CPPFLAGS= $(CPPFLAG) -D_REENTRANT -D_THREAD_SAFE -D$(_OSTYPE_) all : libfoo.so libfoo.so : g++ -fPIC -c $(SRCS) g++ -shared -Wl,-soname,$@ -o $@ $(OBJS) gradle build clean: rm -f *.o core *.out .*list *.ln *.so gradle clean !make clean && make !java -jar build/libs/content-all.jar !ls -lrt /content