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

Copying Data from Java to C++ Objects Array Using JNI

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

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

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

if I can rely on the C++ structure (offset, alignment of the fields, etc.)

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

使用 Point *ByteBuffer(又名 char *)的内容别名化以在以后访问其成员在惯用的 C 中是不可能的。看看 C 标准 N1570 6.5 (p7):

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:88)

— a type compatible with the effective type of the object,

假设您知道 GetDirectBufferAddress 返回的 void * 本身是通过调用 malloc(size) 或朋友(它实际上使用 malloc)返回的,其中 size_t size = sizeof(struct Point) 而不是你可以将它转换为 Point * 本机代码 初始化它的成员,然后再使用它。那将是一种符合标准的方式(其中之一)。