我的 C 库中有一个 unsigned char*,我正在调用一个 JNI 导出的函数,该函数需要使用此数据设置一个 java 对象,最好是在 byte[] 中。
但是这个函数会被调用的很频繁,而且要拷贝的数据也挺多的。
是否可以使用 ByteBuffer 并将该 ByteBuffer 的指针分配给我的 unsigned char*?还是反过来才有效?
我什至可以在不复制数据的情况下执行此操作吗?访问它的最佳方式是什么?
unsigned char* 中数据的大小是已知的。
最佳答案
考虑到您提供的少量信息,这是一个可能的解决方案。
在 Java 方面,您将:
package com.stackoverflow;
public class JNIQuestion
{
static native void fillByteArray(byte[] buffer);
}
在 C 端,您将拥有:
JNIEXPORT void JNICALL Java_com_stackoverflow_JNIQuestion_fillByteArray(JNIEnv* env, jbyteArray array)
{
jboolean isCopy;
jbyte* buffer = (*env)->GetByteArrayElements(env, array, &isCopy);
jsize length = (*env)->GetArrayLength(env, array);
jsize i;
// do something with the buffer here, replace with something meaningful
// PAY ATTENTION TO BUFFER OVERFLOW, DO NOT WRITE BEYOND BUFFER LENGTH
for (i = 0; i < length; ++i)
buffer[i] = i;
// here it is important to use 0 so that JNI takes care of copying
// the data back to the Java side in case GetByteArrayElements returned a copy
(*env)->ReleaseByteArrayElements(env, buffer, 0);
}
使用直接的 ByteBuffer (ByteBuffer.allocateDirect()) 也是一个可能的解决方案。但是,当我需要从 Java 端以非常精确的缓冲区偏移量填充数据时,我只使用直接的 ByteBuffer。
关于性能,使用 byte[] 的解决方案应该令人满意,因为 JVM 很可能在调用 GetByteArrayElements() 时固定字节数组而不是复制它。
一般来说,您会希望尽量减少 JNI 调用的次数,这意味着从 C 端访问对象字段或从 C 端分配 Java 将对性能产生影响。
无论如何,先分析,再优化。
PS:我没有尝试编译代码,可能有错别字。引用JNI Guide和 JNI Tutorial .
关于c - JNI/C 库 : passing byte ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1848886/
我曾尝试搜索Internet和StackOverflow(文章太多,无法计数)但无法找到包含所有这些内容的帮助:比2013年更近开发时不需要Cygwin在Windows上适用于AndroidStudio,而非Eclipse。我是第一次涉足Android开发,我新加入的项目依赖于使用NDK进行开发。我一直在阅读NDK附带的文档,但遇到了这个示例的障碍。我正在尝试构建hello-jni,这是NDK中的示例项目。这是我的环境:AndroidStudio1.4(当前可用的最新稳定版本)NDK版本:r10e操作系统:Windows7Application.mk文件内容:APP_ABI:=all6
我正在努力获取toolJNI4NET工作,以便我可以使用我的C#应用程序中的一些Java代码。作为一个简单的初始测试,我创建了一个简单的Java类库,其中包含一个类Person和一个方法publicStringGetName(){return"NoBody";}。从这里开始,我一直按照JNI下载中提供的示例编辑generateProxies.cmd以创建jar的DLL包装器。我在这方面运气不佳,所以我决定尝试执行相同的操作,但使用示例,特别是名为myJavaDemoCalc的示例。在示例文件夹中执行generateProxies.cmd时会抛出错误。(有需要我会转载这张图)我关注了th
我有一个Fortran格式的Fifp.dll,带有一个简单的voidRESET()函数,并尝试从我的Java代码中调用它。我做了一个简单的java测试类:publicclassTestJni{static{System.loadLibrary("Fifp");}publicnativevoidRESET();}我从中制作了一个.h文件,并编译了它。我还制作了一个桥接文件myBridge.c:#include#include"TestJni.h"externvoidRESET();JNIEXPORTvoidJNICALLJava_TestJni_RESET(JNIEnv*env,jobj
如何在不使用eclipse的情况下调试VisualStudio2003中的JNI代码? 最佳答案 http://www.velocityreviews.com/forums/t152740-jni-debugger.htmlSUMMARY:Basically,theideaisthatyoustartyourJavaprogramunderEclipse,andthentellVCtoattachtotherunningprocesstoo. 关于java-在VisualStudio20
我正在创建一个调用java程序的Windows服务程序。这是部分代码,hModule是一个全局变量,在ServiceStart中调用了LoadLibrary,之后调用了invokeJVM。我设法启动了该服务并且它运行良好,但是,每当我停止该服务时,它都会给我一个错误:Windows无法停止本地计算机上的服务错误1067:Windows服务意外终止添加了额外的日志记录后,发现意外终止错误发生的地方是invokeJVM函数的返回。当我检查事件查看器时,它给了我一些BEX错误,谷歌搜索表明这是一个堆栈溢出错误,但我无法确定它的原因,知道为什么吗?HMODULEhModule;VOIDServ
以下是通过JNI从JavaJVM调用的C++代码的摘录:(JNIEnv*pJniEnv,jobject,jstringpDllName){stringdllName(pJniEnv->GetStringUTFChars(pDllName,NULL));//stuffhappensherelikeHINSTANCEloadedDll=LoadLibrary(dllName.c_str());pJniEnv->ReleaseStringUTFChars(pDllName,dllName.c_str());return...;}这在WindowsXP中有效,但在Windows7中崩溃并出现访
我正在从JNI调用我的nativedll的方法。它工作正常,但在我的native代码中的一个地方,我正在调用exit(1)以便native代码停止工作但发生的事情是它也导致退出我的java应用程序。我错过了什么吗?JNI中是否有任何方法可以让我只能终止native代码而不是整个Java应用程序?编辑:基本上我是用native代码加密文件。我希望它在有人从java取消操作时停止加密。如有任何帮助,我们将不胜感激。 最佳答案 JNInative代码和JVM在同一个进程中运行。由于exit关闭进程,它也将结束JVM。杀死在native代码
目录背景正文layoutxmljavaC++java总结一:追问:C++C++总结二:答疑解惑C++画蛇添足视频不显示黑屏最后感叹科技的更新速度,真的程序员都可能会被替代,下一个时代最大的问题应该是劳动力过剩,导致社会性结构改变,一部分人会被社会性抛弃。背景相机拍摄的画面通过localsocket获取,所以C++的代码可以轻易的获取到每一帧视频数据,需要通过JNI让Android显示出来,方法有两种,一种是在Android内创建回调函数使用Bitmap和ImageView进行赋值显示,另一种也就是ChatGPT完成的,Android将surface传递到JNI层内,C++来完成赋值和渲染,后者
假设我有以下Java代码:publicclassTest{publicstaticintfoo(){thrownewRuntimeException();}}以通常的方式加载native库。native库注册并缓存JVM或其他任何内容,然后稍后执行此函数:JNIEnv*sEnv;//initialisedsomewhereproperlyvoidthrowMeARiver(){jclassc=sEnv->FindClass("Test");jmethodIDm=sEnv->GetStaticMethodID(c,"foo","()I");jinti=sEnv->CallStaticIn
我正在寻找用于单元测试JNI源代码的工具或解决方案。到目前为止,我的搜索车还没有找到任何单元测试JNI代码的解决方案。我的选择是用java编写单元测试并进行native调用,验证返回值。这里的问题是我无法获得代码覆盖率报告。对native实现的调用将需要由nativestub实现进行模拟或支持。java测试代码(调用)--->DLL(JNI)中的native实现--->模拟/stubC++代码如果有任何可用的解决方案,请分享。 最佳答案 确实没有任何全面的工具可用于自动构建和测试JNI代码。我尝试做的是创建一个独立的native库,