我有需要大量计算的Java代码,我想使用JNI将其转发到C ++。
我主要关心的是将所有数据序列化到内存中,然后将计算转发到GPU。
由于数据是用Java接收的,但是主要的计算是使用C ++完成的,所以我想到了将所有数据连续排列在同一结构的原始数组(ByteBuffer
或Unsafe
中的原始字节)中作为C ++对象。
例如,假设我有一个x
和y
的点。在C ++中,对象的大小为24个字节。 (我猜)VTable 8个字节,x
8个字节,y
8个字节。
因此,在Java中,我将所有数据安排在相同的结构中,并使用JNI将缓冲区传递给C ++,然后在C ++中将其转换为点数组。
这很好,我允许自己假设我将始终使用相同的C ++编译器,相同的JDK,相同的操作系统和相同的硬件(至少用于测试该解决方案的可行性)。
我的问题是这些假设是否正确,或者有更好的方法在Java和C ++之间传递序列化数据(我必须使用JNI而不是某种IPC)?
答案 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)
,从本地代码初始化其成员,然后再使用它。那将是一种顺应方式(之一)。