使用JNI将数据从Java复制到C ++对象数组

时间:2019-02-18 19:00:27

标签: java c++ java-native-interface

我有需要大量计算的Java代码,我想使用JNI将其转发到C ++。
我主要关心的是将所有数据序列化到内存中,然后将计算转发到GPU。
由于数据是用Java接收的,但是主要的计算是使用C ++完成的,所以我想到了将所有数据连续排列在同一结构的原始数组(ByteBufferUnsafe中的原始字节)中作为C ++对象。
例如,假设我有一个xy的点。在C ++中,对象的大小为24个字节。 (我猜)VTable 8个字节,x 8个字节,y 8个字节。
因此,在Java中,我将所有数据安排在相同的结构中,并使用JNI将缓冲区传递给C ++,然后在C ++中将其转换为点数组。

这很好,我允许自己假设我将始终使用相同的C ++编译器,相同的JDK,相同的操作系统和相同的硬件(至少用于测试该解决方案的可行性)。

我的问题是这些假设是否正确,或者有更好的方法在Java和C ++之间传递序列化数据(我必须使用JNI而不是某种IPC)?

1 个答案:

答案 0 :(得分:1)

  

如果我可以依靠C ++结构(偏移量,字段对齐等)

否,除非您知道特定平台上的编译器在这种情况下会做什么。会产生不确定的行为。

在惯用的C语言中,无法将ByteBuffer(又名char *)的内容与Point *进行别名化以以后再访问其成员。请查看C标准N1570 {{1} }:

  

一个对象只能由一个对象访问其存储值   具有以下之一的左值表达式    以下类型:88)

     

-与对象的有效类型兼容的类型,

假设您知道6.5 (p7)返回的void *本身是通过调用GetDirectBufferAddress或朋友(实际上使用malloc(size))而返回的,其中malloc比您可以将其强制转换为size_t size = sizeof(struct Point),从本地代码初始化其成员,然后再使用它。那将是一种顺应方式(之一)。