Tag: jni

使用jni从c调用java函数

我正在编写一个简单的程序来从我的C程序中调用Java函数。 以下是我的代码: #include #include #include #include #include #include #include #include #include #include #include #include JNIEnv* create_vm() { JavaVM* jvm; JNIEnv *env; JavaVMInitArgs vm_args; JavaVMOption options[1]; options[0].optionString – “-Djava.class.path=/home/chanders/workspace/Samples/src/ThreadPriorityTest”; vm_args.version = JNI_VERSION_1_6; vm_args.nOptions = 1; vm_args.options = &options; vm_args.ignoreUnrecognized = JNI_FALSE; JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); return env; } void invoke_class(JNIEnv* env) { jclass helloWorldClass; jmethodID mainMethod; jobjectArray […]

Java Native Interface(JNI)是否受C ++ ABI兼容性问题的影响?

Java Native Interface(JNI)是否受C ++ ABI兼容性问题的影响? 我正在开发一个Java应用程序。 我想使用Java Native Interface(JNI)来调用C ++库中的函数。 我可以访问C ++库的代码,我可以重建它,但我可能需要。 (例如,我可以静态链接C ++运行库。) 我可以要求我的用户拥有JRE 6或更高版本,但我不能要求他们拥有任何特定的C ++运行时。 一位同事向我指出了这篇博客文章: http : //www.trilithium.com/johan/2005/06/static-libstdc/ ,它建议不要使用动态加载的C ++代码。 另一位同事向我指出了这个错误报告: http : //bugs.sun.com/bugdatabase/view_bug.do?bug_id=4694590 ,详细说明了如何在Java 1.4.2中解决这些问题。 根据我的理解,问题的要点是libstdc ++的二进制接口经常发生变化。 如果C ++应用程序加载了使用不同编译器构建的C ++共享库,则会同时将两个不兼容的libstdc ++库加载到内存中。 错误报告解释了Java 1.4.2的解决方案:“我们静态链接JDK中的C ++运行时并启用链接器脚本以隐藏libstdc ++和其他内部符号中的符号。结果,这些符号对JNI代码变得不可见,并且当某些符号时本机代码需要调用C ++运行时,调用将使用适当的libstdc ++解析。所以。还有两个libstdc ++。所以同时加载,但它应该是良性的。“ 我有几个问题。 首先,OpenJDK是否继续采用这种方法? [ 编辑:我在OpenJDK的build-dev邮件列表上问了这个问题。 答案是肯定的,HotSpot仍然静态链接libstdc ++,但显然“大多数Linux发行版都将其修补”。 另一位开发人员指出,这甚至不需要补丁:“设置STATIC_CXX = false应该足够了(默认为true)。”] 其次,即使在这种情况下,拥有两个不兼容的libstdc ++是否真的是良性的。所以同时加载? 第三,这种方法(隐藏JDK中的符号)是否解决了所有兼容性问题? 上面引用的博客文章警告说“针对不同ABI编译的代码根本不是二进制兼容的”。 […]

System.loadLibrary不起作用。 链中的第二个lib的UnsatisfiedLinkError

我有通过JNI使用cpp共享库libclient.so的java程序Client.class。 libclient.so构建为共享并使用cpp共享库libhttp.so。 libclient.so和libhttp.so放在文件夹/home/client/lib64 Client.class放在/home/client/bin 客户端可以加载库 System.load和环境变量LD_LIBRARY_PATH System.loadLibrary和-Djava.library.path 第一种方式很好。 export LD_LIBRARY_PATH = /home/client/lib64 java -classpath ./bin客户端 secon方式失败了。 java -classpath ./bin -Djava.library.path=./../lib64 Client java.lang.UnsatisfiedLinkError: /home/client/lib64/libclient.so: libhttp.so: cannot open shared object file: No such file or directory 当我将libhttp.so放入/ usr / lib64时,第二种方式可以正常工作。 如果我使用System.loadLibrary,为什么libclient.so在/ usr / lib64中寻找libhttp.so? 如何在不将libhttp.so复制到/ usr / lib64的情况下修复它? 我的加载代码: //Try load from -Djava.library.path boolean found = false; […]

如果调用JNI DeleteGlobalRef(),相应的java对象是否会被垃圾回收?

我的意思是,如果我在C ++中创建一个全局引用jobject,然后将其传递给某些Java代码,并删除调用DeleteGlobalRef(),那么底层的java对象是否可能立即被垃圾收集,以便任何未来的Java代码已经引用该对象可能会返回NullPointerException? 具体来说,如果我有一些C ++代码执行类似这样的简化示例: static jobject myObjGlobalRef; static JNIEnv* env = /* call to create a JVM and get the JNI env */; jobject ReturnMyObj() { /* <> */ jobject localObj = env->NewObject(class, constructorId, param1); myObjGlobalRef = env->NewGlobalRef(localObj); } void DeleteMyObj() { env->DeleteGlobalRef(myObjGlobalRef); } myObjGlobalRef = ReturnMyObj(); jobject otherExistingGlobalRef = /* Assume we get another […]

从C ++执行Java的简单性

背景信息 :我习惯用Java编程,我知道如何使用Eclipse和Visual Studio。 最终目标 :创建一个GUI,最好是在Visual Studio中,它执行Java函数。 我希望从这个问题中实现 :C ++中的一个按钮,单击它,执行Java函数并将结果返回给C ++。 (可能是通过调用JVM) 我真的怀疑在这里发布这个问题,但我无法在任何地方找到“直截了当”的答案; 因此,我希望有人可以为这个问题展示最简单的解决方案。 我目前考虑了以下数据结构: 通过“常见”文件(如.txt文件)共享数据(但是如何启动Java函数?) 打开一个套接字(这个问题看起来太复杂了) 通过服务器连接(太复杂) 从C ++调用JVM然后执行Java文件(我认为这是最合理的方式,但这需要大量代码) 现在我知道Jace , JNI和SWIG的存在,但我认为它们非常便于制作复杂的程序,而不是简单的接口。 我不想制作一个复杂的程序因此我觉得学习他们所有的命令都很麻烦。 我也读过许多Stack Exchange问​​题,问的问题完全相同,但所有这些问题似乎都给出了非常复杂的答案。 所以这是我的问题: 从C ++执行(如果必要的话:预编译的)Java函数的绝对最简单的方法是什么,其中C ++代码将一些参数传递给此Java函数 提前致谢。

如何通过Java代码影响System.loadLibrary()的搜索路径?

在Java项目中,我使用第三方库来加载一些本机库 System.loadLibrary(“libName”); 我希望能够在我的应用程序中影响此方法的搜索路径,以便用户不需要在命令行上指定正确的java.library.path值(此值取决于当前操作系统和建筑)。 例如在Windows上我想将它设置为“lib / native / windows”,在Linux 32bit上设置为“lib / native / linux32”等。 我试过了 System.setProperty(“java.library.path”, …) 但是这被忽略了,显然是因为JVM在我的代码运行之前只读取了一次该属性。 我还尝试在使用依赖它的Java库之前加载本机库 System.load(“fullPath/lib”) 此调用成功,但是当使用System.loadLibrary()再次加载本机库时,仍会存在UnsatisfiedLinkError。 我发现的唯一方法如下: 添加抽象外部库的整个API的接口。 在其余代码中仅使用这些接口。 添加实现接口的类并委托给库。 写一个自己的ClassLoader,那个 覆盖findLibary(),以便在正确的路径中找到本机库 覆盖loadClass()并自己加载外部库和包装层的所有类,而不是像默认的ClassLoader那样尝试委托给它的父类 确保使用普通的ClassLoader加载接口,并使用我自己的ClassLoader加载包装类和外部库。 这是有效的,但我发现它非常复杂,因为我需要添加所有这些接口。 有更简单的方法吗?

以编程方式设置Java.library.path

我可以从java代码本身以编程方式设置java.library.path吗? 以下不起作用。 System.setProperty(“java.library.path”, “/blah”);

将JNI库添加到本地Maven存储库

我希望使用Maven将JNI库(包括其共享对象(.so)文件)添加到我的项目中。 不幸的是它还没有在公共存储库中,所以我想我必须自己在我的本地存储库上安装它才能使它工作。 如何将Maven中的本机部分包含在我的项目中(最终使用copy-dependencies插件导出)。 这是一个标准的J2SE应用程序(不是网络应用程序),包装.jar? 我试图添加的库是junixsocket ,以防它有助于了解。 它有一个.so(本机库)组件和Java .jar组件。 我遇到了maven-nar-plugin ,似乎是针对原生版本,但似乎更倾向于从代码构建JNI项目,而不是捆绑第三方JNI库,我无法将拼图拼凑在一起。 我该怎么做: 在我的本地存储库中安装这些,具有.jar取决于.so库。 在POM文件中包含依赖项(在.jar和.so上)。 谢谢。

JNI依赖库

我正在通过JNI运行库(我没有写它),并在内部调用另一个DLL。 我收到一个错误,说“找不到依赖库”,除非我把另一个DLL的路径放在系统PATH变量上(我在Windows XP上)。 我希望能够在java命令行上处理这个问题,我已经尝试将它添加到-Djava.library.path并添加到类路径中,两者都没有用(我希望-Djava.library.path可以工作)但不是类路径,但都没有工作)。 有没有办法做到这一点? 谢谢, 杰夫

使用JNI时如何在C ++中获取Javaexception的描述?

我想确定使用JNI从C ++代码调用该函数时Java函数抛出了什么exception。 我有以下代码捕获Javaexception: JNIEnv * pEnv; // assume this is properly initialized jclass javaClass; // ditto jmethodID javaFunction; // ditto pEnv->CallStaticVoidMethod(javaClass, javaFunction); jthrowable exc; if(exc = pEnv->ExceptionOccurred()) { pEnv->ExceptionClear(); } 我不知道如何在此C ++代码中获取有关Javaexception的描述性信息。 有人可以帮忙吗?