首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在安卓系统上通过jni向C传递byte[]时出现问题

在安卓系统上通过jni向C传递byte[]时出现问题
EN

Stack Overflow用户
提问于 2011-08-13 08:44:55
回答 3查看 9.4K关注 0票数 8

我在Java语言中有一个byte[],它报告它的长度为256字节,我将其传递给C语言的本机函数。

当我试图从这个数组中获取数据时,它是完全错误的,当我打印出它时,它与我将其传递给C之前打印出的数据不匹配。

我尝试了几种访问数据的方法,包括GetByteArrayRegionGetByteArrayElements,但似乎都没有给出我想要的数据。

当我调查这个的时候,我试着看看JNI认为GetArrayLengthjbyteArray的长度是多少-它报告的长度是1079142960,远远超过我预期的256个字节。而且每次调用函数的值都是不同的,例如另一次GetArrayLength返回1079145720。

下面是我用来访问数组的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
JNIEXPORT jbyteArray function(JNIEnv* env, jbyteArray array) {
    int length = (*env)->GetArrayLength(env, array);

    jbyte data[256];

    (*env)->GetByteArrayRegion(env, array, 0, 256, data);
    //also tried
    //jbyte *data = (jbyte*) (*env)->GetByteArrayElements(env, array, NULL);
}

这看起来很简单,所以我不太确定到底是怎么回事。这个数组在Java中看起来很好,但它是用C生成的,并被传回,所以我认为可能出了什么问题,Java并不关心它,但当它返回到C时,它会破坏这个数组。

下面是我用来生成数组并将其传递回Java的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//there is some openSSL stuff here that sets up a pointer to an RSA struct called keys that is size bytes large

jbyteArray result = (*env)->NewByteArray(env, size);

(*env)->SetByteArrayRegion(env, result, 0, size, (jbyte*)keys;

我是不是遗漏了什么?

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-13 11:52:34

此函数原型不正确:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
JNIEXPORT jbyteArray function(JNIEnv* env, jbyteArray array)

第二个参数是jclassjobject。如果你的方法是静态的,它应该是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
JNIEXPORT jbyteArray function(JNIEnv* env, jclass cls, jbyteArray array)

如果它不是静态的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
JNIEXPORT jbyteArray function(JNIEnv* env, jobject obj, jbyteArray array)

您将类或对象视为数组,这解释了您获得的意外结果。

票数 12
EN

Stack Overflow用户

发布于 2011-08-13 11:28:55

我认为主要问题是强制将OpenSSL结构转换为字节数组。随着时间的推移,这个结构很可能会被释放。这就解释了当你返回到C语言时,报告给你的奇怪和不同的长度。给Java生成一个RSA*也不会对你有多大的帮助-- Java对这个特殊的结构一无所知,也无法识别它。

你应该尝试的是使用一个

  • i2d_PKCS8PrivateKey_bio(BIO *bp,EVP_PKEY *x,const EVP_CIPHER *enc,char *kstr,int klen,pem_password_cb *cb,EVP_PKEY *u)
  • int i2d_RSA_PUBKEY(RSA *a,unsigned char **pp)

这取决于您是只想将公钥信息传递给Java (see also here),还是同时将私有信息传递给Java。这样,您就可以确保从一开始就处理字节数组。

一旦这对您起作用了(使用您已经尝试过的技术),回到Java,您就可以将字节数组解析成有意义的东西。在公钥的情况下,这很简单:对数组使用X509EncodedKeySpec,并使用KeyFactory#generatePublic生成公钥。

在私钥的情况下,事情稍微复杂一些。OpenSSL只理解PKCS#8 format,而默认情况下,Java按照PKCS#1格式对其私钥进行编码。但是您已经可以使用i2d_PKCS8PrivateKey_bio将密钥转换为PKCS#8。不过,您需要首先将RSA*包装为EVP_PKEY*

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
EVP_pkey *pkey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey, rsa);

不要加密您的密钥并使用in-memory BIO,然后将生成的字节数组传递给Java,并在那里传递给PKCS8EncodedKeySpec的构造函数,最后使用KeyFactory生成您的私钥。

票数 1
EN

Stack Overflow用户

发布于 2011-08-13 09:09:38

请尝试在字符串后追加'\0‘字符。可能它不能识别字符串的结尾。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7049437

复制
相关文章
Python 列表是否线程安全?
Python中的列表不是线程安全的,在多线程环境下,对列表的操作可能会导致数据冲突或错误。但是,并非所有列表操作都是线程不安全的。如果操作是原子的,也就是说不能被线程调度机制打断,那么就没有问题。比如L.append(x)和L.pop()就是原子操作,所以是thread安全。如果操作不是原子的,或者涉及修改多个列表元素,那么就需要使用锁或者其他同步机制来保证线程安全。例如,Li = Lj 和 L.append(L- 1) 不是原子操作,因此它们可能会导致冲突。可以使用 dis 模块来检查操作是否是原子操作。
jackcode
2023/05/29
3860
Python 列表是否线程安全?
[Python时间相关] 推迟调用线程的运行 time sleep()
参考链接: Python中的时间函数 1(time(),ctime(),sleep()…)
用户7886150
2020/12/22
1K0
Linux下的strerror是否线程安全?
man strerror即可看到相关说明,strerror_r是线程安全的,但不带_r的strerror是非线程安全的。
一见
2019/03/14
1.3K0
printf的线程安全性以及cout的线程不安全性验证,以及意外收获
码给你,自测。 #include <iostream> #include <thread> #include <atomic> #include <ctime> #include <mutex> using namespace std; std::atomic_int a; //int a; std::mutex _mutex; void add_() { for (int i = 0; i < 10000; i++) { _mutex.lock(); a++; _mutex.unlock
看、未来
2021/10/20
7700
JAVA中的线程安全
     就是线程同步的意思,就是当一个程序对一个线程安全的方法或者语句进行访问的时候,其他的不能再对他进行操作了,必须等到这次访问结束以后才能对这个线程安全的方法进行访问
用户10175992
2023/10/17
1600
JAVA中的线程安全
Toast在子线程调用的问题
如果在子线程调用那么让Toast能正常显示的方式是在它之前和之后调用Looper.prepare()和Looper.loop()
PhoenixZheng
2018/08/07
8030
QThread是否为分离线程运行呢?
❝前一阵子有个小伙伴在群提问,今天特意找下源码看看。❞ 分离线程:当线程被设置为分离状态后,线程结束时,它的资源会被系统自动回收。 非分离线程:当线程被设置为非分离状态后,必须在另一个线程中使用pthread_join()等待其结束,否则会变成"僵尸线程"。 unix平台QThread实现是「分离线程」。 // qt-everywhere-src-5.12.1\qtbase\src\corelib\thread\qthread_unix.cpp void QThread::start(Priority pr
Qt君
2023/03/17
6050
QThread是否为分离线程运行呢?
多线程是同时执行多个线程的吗
相信多线程各位大佬都用过,不管是在单核cpu还是多核cpu上都可以执行,但是多线程是同时执行多个线程的吗?
余生大大
2022/11/02
1.1K0
子线程调用UI线程的方法
vs2005中,子线程不允许使用UI中的控件,网上的解决方法都有:使用控件的Invoke,不过在我自己的应用中总觉得麻烦:我要从子线程中调用一个主线程中的处理,要用一次委托,而Invoke还要用委托,绕来绕去,把人绕的很晕。我稍微改了一下结构,可以比较方便的达到在子线程中调用UI线程中的处理函数。 在线程类中,定义 public delegate void ReceivedHandlerUI(object obj);     //接收处理,涉及UI 使用两个变量,第二个只要是界面中的任意控件都行,主要是利
用户1075292
2018/01/23
1.2K0
【Java】线程、线程安全、线程状态
昨天的时候我们已经写过一版多线程的代码,很多同学对原理不是很清楚,那么我们今天先画个多
陶然同学
2023/02/27
1.8K0
【Java】线程、线程安全、线程状态
线程安全类在性能测试中应用
首先验证接口参数签名是否正确,然后加锁去判断订单信息和状态,处理用户增添VIP时间事务,成功之后释放锁。锁是针对用户和订单的分布式锁,使用方案是用的redis。
FunTester
2020/02/17
8630
多线程---线程安全
一、思考:线程安全产生的原因是什么? 二、final,volatile关键字的作用? 三、1.5之前的javaDCL有什么缺陷? 四、如何编写线程安全的程序? 五、ThreadLocal使用的注意事项有哪些?
用户9854323
2022/06/25
6100
多线程---线程安全
Java static 静态方法 并发(是否线程安全)
public class TestUitl { public static User setName(User user,String name) { User u = user; u.name = name; return u; } } 如上面的代码所示,在 setName 这个static方法里面u会不会有线程安全问题呢? 答案是不确定的,为什么呢? 首先说明一点,方法属于一个程序块,只有当别人调
用户1688446
2018/05/08
4.5K0
线程与线程安全
电脑中时会有很多单独运行的程序,每个程序有一个独立的进程,而进程之间是相互独立存在的。比如下图中的QQ、酷狗播放器、电脑管家等等。
狼啸风云
2019/11/28
7020
Java多线程编程中的线程安全与最佳实践
Java的多线程编程中,线程安全是一个关键概念。线程安全指的是多个线程同时访问共享数据时,不会导致数据损坏或不一致的状态。为了实现线程安全,可以使用同步机制,如synchronized关键字或Lock接口,来保护共享资源的访问。此外,Java提供了线程安全的集合类,如ConcurrentHashMap和CopyOnWriteArrayList,用于处理多线程环境下的数据共享。正确的线程安全实践可以确保程序在多线程环境下稳定可靠地运行,避免竞态条件和数据冲突问题。
杨不易呀
2023/09/27
2700
Java多线程编程中的线程安全与最佳实践
【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )
在 Android 中 , 如果要判定当前线程是否是主线程 , 可以使用如下方法进行判定 ;
韩曙亮
2023/03/29
1.2K0
jdk8 hashmap线程安全吗_Python中的线程
只要是对于集合有一定了解的一定都知道HashMap是线程不安全的,我们应该使用ConcurrentHashMap。但是为什么HashMap是线程不安全的呢,之前面试的时候也遇到到这样的问题,但是当时只停留在***知道是***的层面上,并没有深入理解***为什么是***。于是今天重温一个HashMap线程不安全的这个问题。
全栈程序员站长
2022/11/07
7750
jdk8 hashmap线程安全吗_Python中的线程
在现有线程安全类中添加功能
Java类库中包含许多有用的“基础模块”类。通常应该优先选择重用这些类而不是开发新类:重用能降低开发工作量、开发风险以及维护成本。很多情况这些现有的类只能提供大部分工作,我们需要在不破坏线程安全的情况下添加一些新的操作。 要添加一个新的原子操作,有以下几种方法: 第一种:修改原始的类 这种方法最简单最安全。但通常情况下无法访问或修改类的源代码。 第二种:扩展类机制(通过继承) 下面的代码中BetterVector扩展了Vector,并添加了新方法putIfAbsent。但并非所有的类都像Vector那样将状
SuperHeroes
2018/05/31
7120
多线程 以及 线程安全
进程: APP 启动时,应用会启动一个新的 Linux 进程, 一个app内可以有多个进程,进程之间不共享数据。 线程: 1个进程中可以包含多个线程,线程之间数据共享。
艳龙
2021/12/16
4080
多线程 以及 线程安全
java 多线程线程安全
在多线程中使用共享资源,对共享资源的操作不是原子性,就会导致数据不一致的情况 例如 : index ++ 操作 index ++ 实际上相当于 1. index + 1 2. 将结果赋值 index
Tim在路上
2020/08/04
8110

相似问题

让printf线程安全吗?

181

方法是否从单独的线程调用,在调用线程上运行?

32

是否可以在c中同时运行主线程及其子线程?

11

在单个线程中调用和销毁类实例时线程是否安全?

34

同时从多个线程调用写()安全吗?

20
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文