草庐IT

c - JNI/C 库 : passing byte ptr

coder 2023-12-29 原文

我的 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 GuideJNI Tutorial .

关于c - JNI/C 库 : passing byte ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1848886/

有关c - JNI/C 库 : passing byte ptr的更多相关文章

  1. android - Windows 上的 Hello-Jni,Android NDK - build-local.mk : No such file - 2

    我曾尝试搜索Internet和StackOverflow(文章太多,无法计数)但无法找到包含所有这些内容的帮助:比2013年更近开发时不需要Cygwin在Windows上适用于AndroidStudio,而非Eclipse。我是第一次涉足Android开发,我新加入的项目依赖于使用NDK进行开发。我一直在阅读NDK附带的文档,但遇到了这个示例的障碍。我正在尝试构建hello-jni,这是NDK中的示例项目。这是我的环境:AndroidStudio1.4(当前可用的最新稳定版本)NDK版本:r10e操作系统:Windows7Application.mk文件内容:APP_ABI:=all6

  2. java - 无法使用 JNI4NET 工具生成 C# 代理 dll,将批处理文件作为可信程序集运行? - 2

    我正在努力获取toolJNI4NET工作,以便我可以使用我的C#应用程序中的一些Java代码。作为一个简单的初始测试,我创建了一个简单的Java类库,其中包含一个类Person和一个方法publicStringGetName(){return"NoBody";}。从这里开始,我一直按照JNI下载中提供的示例编辑generateProxies.cmd以创建jar的DLL包装器。我在这方面运气不佳,所以我决定尝试执行相同的操作,但使用示例,特别是名为myJavaDemoCalc的示例。在示例文件夹中执行generateProxies.cmd时会抛出错误。(有需要我会转载这张图)我关注了th

  3. java - 使用 JNI 从 java 调用 fortran dll - 2

    我有一个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

  4. java - 在 VisualStudio 2003 中调试 JNI 代码 - 2

    如何在不使用eclipse的情况下调试VisualStudio2003中的JNI代码? 最佳答案 http://www.velocityreviews.com/forums/t152740-jni-debugger.htmlSUMMARY:Basically,theideaisthatyoustartyourJavaprogramunderEclipse,andthentellVCtoattachtotherunningprocesstoo. 关于java-在VisualStudio20

  5. java - 使用 Windows 服务调用使用 JNI 和 LoadLibrary 的 Java 程序的问题 - 2

    我正在创建一个调用java程序的Windows服务程序。这是部分代码,hModule是一个全局变量,在ServiceStart中调用了LoadLibrary,之后调用了invokeJVM。我设法启动了该服务并且它运行良好,但是,每当我停止该服务时,它都会给我一个错误:Windows无法停止本地计算机上的服务错误1067:Windows服务意外终止添加了额外的日志记录后,发现意外终止错误发生的地方是invokeJVM函数的返回。当我检查事件查看器时,它给了我一些BEX错误,谷歌搜索表明这是一个堆栈溢出错误,但我无法确定它的原因,知道为什么吗?HMODULEhModule;VOIDServ

  6. java - JNI 中的 JVM-Crash 调用 ReleaseStringUTFChars,仅在 Windows 7、Windows XP 上正常 - 2

    以下是通过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中崩溃并出现访

  7. java - 从 JNI 中的 native 代码退出会杀死 Java 应用程序 - 2

    我正在从JNI调用我的nativedll的方法。它工作正常,但在我的native代码中的一个地方,我正在调用exit(1)以便native代码停止工作但发生的事情是它也导致退出我的java应用程序。我错过了什么吗?JNI中是否有任何方法可以让我只能终止native代码而不是整个Java应用程序?编辑:基本上我是用native代码加密文件。我希望它在有人从java取消操作时停止加密。如有任何帮助,我们将不胜感激。 最佳答案 JNInative代码和JVM在同一个进程中运行。由于exit关闭进程,它也将结束JVM。杀死在native代码

  8. [chatGPT] 如何通过JNI在Android上显示实时视频流 - 2

    目录背景正文layoutxmljavaC++java总结一:追问:C++C++总结二:答疑解惑C++画蛇添足视频不显示黑屏最后感叹科技的更新速度,真的程序员都可能会被替代,下一个时代最大的问题应该是劳动力过剩,导致社会性结构改变,一部分人会被社会性抛弃。背景相机拍摄的画面通过localsocket获取,所以C++的代码可以轻易的获取到每一帧视频数据,需要通过JNI让Android显示出来,方法有两种,一种是在Android内创建回调函数使用Bitmap和ImageView进行赋值显示,另一种也就是ChatGPT完成的,Android将surface传递到JNI层内,C++来完成赋值和渲染,后者

  9. java - Java 方法在抛出异常时返回给 JNI 调用者的是什么? - 2

    假设我有以下Java代码:publicclassTest{publicstaticintfoo(){thrownewRuntimeException();}}以通常的方式加载native库。native库注册并缓存JVM或其他任何内容,然后稍后执行此函数:JNIEnv*sEnv;//initialisedsomewhereproperlyvoidthrowMeARiver(){jclassc=sEnv->FindClass("Test");jmethodIDm=sEnv->GetStaticMethodID(c,"foo","()I");jinti=sEnv->CallStaticIn

  10. java - 如何对JNI源码进行单元测试? - 2

    我正在寻找用于单元测试JNI源代码的工具或解决方案。到目前为止,我的搜索车还没有找到任何单元测试JNI代码的解决方案。我的选择是用java编写单元测试并进行native调用,验证返回值。这里的问题是我无法获得代码覆盖率报告。对native实现的调用将需要由nativestub实现进行模拟或支持。java测试代码(调用)--->DLL(JNI)中的native实现--->模拟/stubC++代码如果有任何可用的解决方案,请分享。 最佳答案 确实没有任何全面的工具可用于自动构建和测试JNI代码。我尝试做的是创建一个独立的native库,

随机推荐