Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c代码的java包装器_Java_C_Java Native Interface_Swig - Fatal编程技术网

c代码的java包装器

c代码的java包装器,java,c,java-native-interface,swig,Java,C,Java Native Interface,Swig,我有以下c代码: 测试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() {

我有以下c代码:

测试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";
}
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;
}
我想为这个.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)
线程“main”java.lang.UnsatisfiedLinkError中出现异常:java.library.path中没有测试应用程序包装
位于java.lang.ClassLoader.loadLibrary(ClassLoader.java:1856)
位于java.lang.Runtime.loadLibrary0(Runtime.java:845)
位于java.lang.System.loadLibrary(System.java:1084)
在HelloWorld。(HelloWorld.java:4)

我做错了什么?

您似乎不了解jni是如何工作的,请查看本教程:

您的
test\u app\u wrap
不存在,要使用JNI,您必须为您的C函数指定一个特定的名称,然后使用本机方法创建一个Java类来调用它们,即

native String print_hello();
并且,在Java类中,加载本机库


然后,您将创建一个YourClass Java对象并调用
print\u hello()
native方法

当您执行
swig-Java test\u app.i
时,它将创建一些必须包含在Java项目中的Java glue类。生成的主界面名为
test\u 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\u appJNI
,这也是自动生成的,并充当本机代码的粘合剂(使用
native
方法):

因此,你应该:

  • 在项目中包括生成的
    .java
    文件
  • 确保使用
    System.loadLibrary(“test_app_wrap”)加载
    .so
    -您已经这样做了
  • 只需调用
    test\u app.print\u hello()
此外,建议阅读:SWIG手册中的章节。预备课程和基本C/C++包装部分的介绍很好地解释了所有的基础知识

您得到的错误表明JVM无法加载
.so
库。我的第一个问题是它是否被正确编译和链接。如果您确定您有
libtest\u app\u wrap.so
,那么它可能不在JVM查找它的路径上(选中此-)。例如,对我来说,有必要将
-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();
    }
}

希望有帮助:)

非常感谢您的重播。当运行swig-java test_app.i时,我得到test_app_wrap.c、test_appJNI.java和SWIGTYPE_p_int.java的返回。你说得对,那本书是空白的。在我的例子中,print_hello方法返回一个字符串。我猜它将是原生字符串print_hello();我说的对吗?检查教程,它准确地解释了为了让你的JNI正常工作你必须做什么我检查了教程。非常感谢你。在我的例子中,我有test_app_wrapper.c(由swig创建)。无需创建新的ctest.c(如教程中所述)。您能告诉我/path/to/jdk/headers的路径是什么吗?非常感谢。您确定生成的文件吗?对我来说,
swig
也生成了
test\u app.java
(是的,我试过编译你的模块)。是的,你是对的。我忘了提到test_app.java。我确实编辑了我的问题。你能看一下吗?你所说的导入测试应用程序是什么意思?非常感谢。我指的是普通的旧Java
importtest\u应用程序。哦,等等,你不需要显式导入(我已经很久没有使用Java了)。刚刚编辑完我的答案-我想现在已经足够详细了!非常感谢你!你是一个真正的帮手!!我修改了HelloWorld.java文件并从命令行运行java-Djava.library.path=.HelloWorld,但仍然存在错误:线程“main”java.lang.unsatifiedlinkerror:no test_app_wrap in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1856)at java.lang.Runtime.loadLibrary0(Runtime.java:845)位于HelloWorld的java.lang.System.loadLibrary(System.java:1084)(HelloWorld.java:3)
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 -Djava.library.path=. HelloWorld
public class HelloWorld {
    static {
        System.loadLibrary("test_app_wrap"); 
    }
    static public void main(String argv[]) {
        test_app.print_hello();
    }
}