[英]java wrapper for .c code
我有以下c代碼:
test.c的
#include <stdio.h>
#include <math.h>
int add (int a, int b)
{
a=4;
b=4;
return a+b;
}
int add_pointer (int *a, int *b)
{
printf("values of a,b: %d,%d \n",*a,*b);
return ((*a)+(*b));
}
char* print_hello()
{
return "hello_world";
}
test.h
#ifndef TEST_H_
#define TEST_H_
int add(int a, int b);
int add_pointer (int *a, int *b);
char *print_hello();
#endif
main.c中
#include "test.h"
#include <stdio.h>
#include <math.h>
int main()
{
int a,b,c,d;
char* rez;
a=5;
b=2;
//int *r=&a;
c= add(a,b);
d=add_pointer(&a,&b);
rez=print_hello();
printf("sum is: %d and : %s %d \n",c,rez,d);
return 0;
}
test_app.i
%module test_app
%{
#include "test.h"
%}
%include "test.h"
我想創建一個這個.c代碼的java包裝器。 我想稍后在Android演示中使用這個包裝器。
我做了以下事情:
$: swig -java test_app.i
得到:
test_app_wrapper.c
test_app.java
test_appJNI.java
SWIGTYPE_p_int.java
$: gcc -fpic -c test.c test_app_wrap.c -I /usr/lib/jvm/java-7-openjdk-amd64/include -I /usr/lib/jvm/java-7-openjdk-amd64/include/linux
$: gcc -shared test.o test_app_wrap.o -o libtest_app_wrap.so
更新:
HelloWorld.java
public class HelloWorld {
native String print_hello(); /* (1) */
static {
System.loadLibrary("test_app_wrap"); /* (2) */
}
static public void main(String argv[]) {
HelloWorld helloWorld = new HelloWorld();
helloWorld.print_hello(); /* (3) */
}
}
運行時:
$: javac HelloWorld.java
$ java HelloWorld
我有:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no test_app_wrap in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1856)
at java.lang.Runtime.loadLibrary0(Runtime.java:845)
at java.lang.System.loadLibrary(System.java:1084)
at HelloWorld.<clinit>(HelloWorld.java:4)
我究竟做錯了什么?
看來你不明白jni是如何工作的,請查看本教程:
你的test_app_wrap
不存在,使用JNI你必須為你的C函數分配一個特定的名稱,然后使用本機方法創建一個Java類來調用它們,即
native String print_hello();
並且,在Java類中,加載本機庫。
然后,您將創建一個YourClass Java對象並調用print_hello()
本機方法
當您執行swig -java test_app.i
,它會創建一些必須包含在Java項目中的Java glue類。 生成的主界面名為test_app.java
,如下所示:
public class test_app {
public static int add(int a, int b) {
return test_appJNI.add(a, b);
}
public static int add_pointer(SWIGTYPE_p_int a, SWIGTYPE_p_int b) {
return test_appJNI.add_pointer(SWIGTYPE_p_int.getCPtr(a), SWIGTYPE_p_int.getCPtr(b));
}
public static String print_hello() {
return test_appJNI.print_hello();
}
}
如您所見,它將所有調用委托給test_appJNI
,這也是自動生成的,並充當本機代碼的test_appJNI
(使用native
方法):
public class test_appJNI {
public final static native int add(int jarg1, int jarg2);
public final static native int add_pointer(long jarg1, long jarg2);
public final static native String print_hello();
}
所以,你應該:
.java
文件 System.loadLibrary("test_app_wrap");
加載.so
庫System.loadLibrary("test_app_wrap");
- 你已經做到了 test_app.print_hello()
另外,推薦閱讀:SWIG手冊中的21 SWIG和Java部分。 預備和基本C / C ++包裝部分的介紹很好地解釋了所有基礎知識。
您獲得的錯誤表明JVM無法加載.so
庫。 我的第一個問題是它是否正確編譯和鏈接。 如果你確定你有libtest_app_wrap.so
,它可能不在JVM尋找它的路徑上(請查看 - http://www.chilkatsoft.com/p/p_499.asp )。 例如,對我來說,有必要添加-Djava.library.path=.
到Java命令行:
java -Djava.library.path=. HelloWorld
供參考 - 我修改了你的HelloWorld.java
文件:
public class HelloWorld {
static {
System.loadLibrary("test_app_wrap");
}
static public void main(String argv[]) {
test_app.print_hello();
}
}
希望有幫助:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.