Копирование данных из Java в массив объектов C ++ с использованием JNI - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть Java-код, который требует интенсивных вычислений, которые я хотел бы переслать в C ++ с использованием JNI.
Моя основная задача состоит в том, чтобы все данные были сериализованы в памяти, а затем пересылать вычисления в GPU.
Так какданные получены в Java, но основные вычисления выполняются с использованием C ++, я думал о том, чтобы расположить все данные непрерывно в необработанном массиве (ByteBuffer или необработанных байтах из Unsafe), в той же структуре, что и объект C ++.
Например, предположим, у меня есть точка с x и y.В C ++ объект имеет размер 24 байта.8 байтов для (я думаю) VTable, 8 байтов для x и 8 байтов для y.
Так что в Java я бы расположил все данные в одной структуре и передал буфер в C ++ с помощью JNI, а в C ++ привел его к массиву точек.

Это сработало, и япозволяя себе предположить, что я всегда буду использовать один и тот же компилятор C ++, тот же JDK, ту же ОС и то же HW (по крайней мере, для проверки возможности решения).

Мой вопрос заключается в том, верны ли эти предположения, илиЕсть ли лучший способ передачи сериализованных данных между Java и C ++ (я должен использовать JNI, а не какой-нибудь IPC)?

1 Ответ

0 голосов
/ 21 февраля 2019

если я могу положиться на структуру C ++ (смещение, выравнивание полей и т. Д.)

Нет, если вы не знаете, что будет делать в этом ваш компилятор на вашей конкретной платформедело.Это приводит к неопределенному поведению.

Псевдоним содержимого ByteBuffer (он же char *) с Point * для последующего доступа к его элементам невозможен в идиоматическом языке C. Посмотрите на стандарт C N1570 6.5 (p7):

Доступ к сохраненному значению объекта должен осуществляться только через выражение lvalue, имеющее один из следующих типов: 88)

- тип, совместимый с действующим типом объекта.object,

Предполагая, что вы знаете, что void *, возвращаемый GetDirectBufferAddress, сам по себе возвращается при вызове malloc(size) или друзьям (на самом деле он использует malloc), где size_t size = sizeof(struct Point), чем вы можетеприведите его к Point *, инициализируйте его член из нативного кода и позже используйте его.Это было бы соответствующим образом (один из).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...