4

私は次の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)

私は何を間違っていますか?

4

2 に答える 2

2

jni の仕組みを理解していないようです。このチュートリアルを確認してください。

JNI を使用して Java から C コードを呼び出す

あなたtest_app_wrapは存在しません.JNIを使​​用するには、C関数に特定の名前を割り当ててから、それらを呼び出すネイティブメソッドを持つJavaクラスを作成する必要があります.

native String print_hello();

そして、Java クラスで、ネイティブ ライブラリをロードします。

次に、YourClass Java オブジェクトを作成し、print_hello()ネイティブ メソッドを呼び出します。

于 2013-03-22T08:45:25.130 に答える
1

を実行するswig -java test_app.iと、Javaプロジェクトに含める必要のあるJavaグルークラスがいくつか作成されます。生成されるメインインターフェイスには名前が付けられ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。これも自動的に生成され、ネイティブコードへの接着剤として機能します(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のファイルをプロジェクトに含める
  • .soライブラリをロードすることを確認してくださいSystem.loadLibrary("test_app_wrap");-すでに実行しています
  • 単に電話するtest_app.print_hello()

また、推奨される読み物:SWIGマニュアルの21SWIGおよびJavaセクション。予備知識基本的なC/C ++ラッピングセクションのツアーでは、すべての基本を非常によく説明しています。

.so表示されるエラーは、JVMがライブラリをロードできないことを示しています。私の最初の質問は、それが適切にコンパイルおよびリンクされているかどうかです。持っていることが確実な場合は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();
    }
}

お役に立てば幸いです:)

于 2013-03-22T08:52:50.723 に答える