簡體   English   中英

.c代碼的java包裝器

[英]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是如何工作的,請查看本教程:

使用JNI從Java調用C代碼

你的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");加載.soSystem.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM