Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.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++_Eclipse_C++11_Java Native Interface - Fatal编程技术网

呼叫C++;来自Java的函数

呼叫C++;来自Java的函数,java,c++,eclipse,c++11,java-native-interface,Java,C++,Eclipse,C++11,Java Native Interface,这是我关于StackOverflow的第一篇文章。我正在做一个项目,我需要你在JNI的帮助。我被困在那里。。。我最近一直在阅读和尝试它,但仍然不知道如何使它工作 我在C++中创建了一个静态库(下面是伪代码): 我所需要的就是能够使用accessZ()函数将一些参数从Java传递到libXYZ 新编辑: public final class NativeClass { { System.loadLibrary("myLibrary"); } public native voi

这是我关于StackOverflow的第一篇文章。我正在做一个项目,我需要你在JNI的帮助。我被困在那里。。。我最近一直在阅读和尝试它,但仍然不知道如何使它工作

我在C++中创建了一个静态库(下面是伪代码):

我所需要的就是能够使用accessZ()函数将一些参数从Java传递到libXYZ

新编辑:

public final class NativeClass {
  {
    System.loadLibrary("myLibrary");
  }

  public native void accessZ(char a_uint, String b_string, char[] c_vector);

  public static final NativeClass getInstance() {
    return INSTANCE;
  }

  private static final NativeClass INSTANCE = new NativeClass();
};

您不能直接调用这样的函数,您将从JNI调用的函数必须具有特定名称和特定形式,并且必须由某个Java类中的成员函数表示。(另外,Java没有无符号整数,因此您的
uint8\u t
可能必须是
char
或其他一些基本类型,同样地,您需要考虑在Java中什么将表示
std::vector

  • 使Java函数可公开访问(不幸的是,它不能是静态的,类实例很重要)

  • 让本机实现只提取参数并调用
    accessZ()

  • 通常,您的代码看起来像

    public final class NativeClass {
    
      {
        System.loadLibrary("myLibrary");
      }
    
      public native void accessZ(char a_uint, String b_string, char[] c_vector);
    
      public static final NativeClass getInstance {
        return INSTANCE;
      }
    
      private static final NativeClass INSTANCE = new NativeClass();
    
    };
    
    然后,您的
    myLibrary.cpp
    必须包含
    “api.h”
    ,并包含一个与

    JNIEXPORT void JNICALL Java_NativeClass_accessZ(JNIEnv *env, jobject obj, jchar ja_uint, jstring jb_string, jcharArray jc_vector) {
    
      uint8_t a_uint = (uint8_t)ja_uint;
    
      const char *cfn = env->GetStringUTFChars(jb_string, 0);
      std::string b_string{cfn};
      env->ReleaseStringUTFChars(jb_string, cfn);
    
      size_t sz = env->GetArrayLength(jc_vector);
      std::vector<uint8_t> c_vector(sz);
      jchar *c_array = env->GetCharArrayElements(jc_vector, NULL);
      for(size_t i = 0; i < sz; i++)
        c_vector[i] = c_array[i];
      env->ReleaseCharArrayElements(jc_vector, c_array, 0);
    
      accessZ(a_uint, b_string, c_vector);
    
    }
    
    此函数将成为库的访问点,但随后可以执行任何它想做的操作,它可以创建对象,调用对象上的函数,甚至可能保持暂时状态,因为库将在调用之间保持运行。(不过,最好对传递给函数的状态对象进行操作。)库可能会向Java公开任意多个函数,如下所示

    以下是我的命令行(适用于Linux):


    您看过任何现有的jni教程吗?为什么你希望我们为你写下明确的东西。。。这已经被记录了无数次了?@GhostCat:我当然看过JNI教程了。但是,它们都是用C++编写的特定函数,而不是函数库中的函数。在那里使用C++函数…不是存储在某个库或dll中-它们只是生活在某个真空中?!非常感谢您的评论和时间。。。我对JNI完全陌生。所以,如果你知道/有一些有用的链接/教程(不像HelloWorld JNI示例)来解决我的问题,请把它放在那里;也许,我错过了一些搜索结果。。。否则,我没有时间去讨论无用的讨论……你必须告诉我们你尝试了什么,也就是说,调用C++函数的java代码。作为建议,最好从一个非常简单的函数开始实验,比如
    intgetint(){return 123;}
    。否则,我们不清楚您希望我们给出什么样的答案,不会复制大量现有的关于JNI的免费在线教程或教科书章节。请记住,堆栈溢出与特定问题有关。你也不应该听起来那么苛刻。我是说,“我需要直接的回答”,来吧。。。这可不是你付钱给我们的。嗨@Vee,非常感谢你的回复。今天晚些时候(如果我有时间)我会试试,然后再给你回复。实际上,在这期间,我只需要将参数从java传递到C++,其中访问()函数返回空(即,空)。稍后,当我完成这个步骤(java -C++通信)时,我希望Access()返回布尔值;但现在我只关注问题的一部分。干杯。@M_Square我的代码包含一些错误。我现在测试并修复了它们,所以请尝试使用新版本。非常感谢您的努力。我昨天尝试过(多次使用不同的设置)用javah编译,但是上面提供的类没有编译。。。当我运行
    javah-jni NativeClass.java
    时,我遇到了以下错误:
    线程“main”java.io.IOException中的异常:在java.net.URLClassLoader{url=[文件:/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre/lib/rt.jar],parent=gnu.gcj.runtime.SystemClassLoader{URL=[文件:./],parent=gnu.gcj.runtime.ExtensionClassLoader{url=[],parent=null}}}}在gnu.classpath.tools.javah.Main.getClass(libgcj tools.so.16)在gnu.classpath.tools.javah.Main.parseClasses(libgcj tools.so.16)在gnu.classpath.tools.javah.Main.Main(libgcj tools.so.16)运行(libgcj tools.so.16)
    有什么想法吗?BR@M_Square这是个奇怪的名字,
    NativeClass/java.class
    。这是一个“未找到文件”错误,与文件中的内容无关。编译其他类没有问题吗?您是否有
    NativeClass
    遵循相同的文件命名条件?如果它是包
    x.y.z
    中的公共类,则需要在名为
    x/y/z/NativeClass.java
    的文件中找到它。(另外,C方法的名称是
    Java_x_y_z_NativeClass_accessZ
    )在我的示例中,它不在任何包中。
    public final class NativeClass {
    
      {
        System.loadLibrary("myLibrary");
      }
    
      public native void accessZ(char a_uint, String b_string, char[] c_vector);
    
      public static final NativeClass getInstance {
        return INSTANCE;
      }
    
      private static final NativeClass INSTANCE = new NativeClass();
    
    };
    
    JNIEXPORT void JNICALL Java_NativeClass_accessZ(JNIEnv *env, jobject obj, jchar ja_uint, jstring jb_string, jcharArray jc_vector) {
    
      uint8_t a_uint = (uint8_t)ja_uint;
    
      const char *cfn = env->GetStringUTFChars(jb_string, 0);
      std::string b_string{cfn};
      env->ReleaseStringUTFChars(jb_string, cfn);
    
      size_t sz = env->GetArrayLength(jc_vector);
      std::vector<uint8_t> c_vector(sz);
      jchar *c_array = env->GetCharArrayElements(jc_vector, NULL);
      for(size_t i = 0; i < sz; i++)
        c_vector[i] = c_array[i];
      env->ReleaseCharArrayElements(jc_vector, c_array, 0);
    
      accessZ(a_uint, b_string, c_vector);
    
    }
    
    NativeClass.INSTANCE.accessZ((char)10, "abc", new char[]{3, 5, 7});
    
    g++ -isystem /usr/java/jdk1.8.0_101/include/ -isystem /usr/java/jdk1.8.0_101/include/linux myLibrary.cpp -c -fPIC
    (creates myLibrary.o)
    
    g++ myLibrary.o libXYZ.a -shared -o libmyLibrary.so
    (creates libmyLibrary.so)