После моего предыдущего вопроса и ответа Some Name , я хотел бы попробовать противоположный способ и улучшить предыдущий вопрос:
Iхотел бы сделать следующие шаги:
- Выделить буфер в Java
- Заполнить массив в C ++
- Редактировать значения в Java
- Doнекоторый перебор чисел в C ++
- Считывание значений в Java
Рассмотрим следующий класс в C ++:
#pragma once
#pragma pack(push, 8)
class Point
{
public:
double x;
double y;
Point();
virtual ~Point();
void ebeProduct(Point &other) {
x = x * other.x;
y = y * other.y;
}
};
Point::Point()
{
}
Point::~Point()
{
}
#pragma pack(pop)
Следующий фрагмент кода:
Point point = Point();
std::cout << "Size of Point: " << sizeof(Point) << std::endl;
std::cout << "Address is: " << &point << std::endl;
std::cout << "x address is: " << &(point.x) << " and offset is: " << (long long)&(point.x) - (long long)&point << std::endl;
std::cout << "y address is: " << &(point.y) << " and offset is: " << (long long)&(point.y) - (long long)&point << std::endl;
показывает следующий результат:
Size of Point: 24
Address is: 000000D45B0FF2C0
x address is: 000000D45B0FF2C8 and offset is: 8
y address is: 000000D45B0FF2D0 and offset is: 16
Так что теперь я могу предположить следующие размеры в Java:
final int NUMBER_OF_POINTS = 10;
final int SIZE_OF_POINT = 24;
final int X_OFFSET = 8;
final int Y_OFFSET = 16;
Далее я выделю область памяти, используя unsafe
и вызовите public static native void allocatePoints(long address, int numberOfPoints);
Чтобы заполнить их Point
объектами:
long address = unsafe.allocateMemory(NUMBER_OF_POINTS * SIZE_OF_POINT);
allocatePoints(address, NUMBER_OF_POINTS);
Код C ++, который заполняет точки:
Point * points = (Point *) address;
for (int pointIndex = 0; pointIndex < numberOfPoints; pointIndex++) {
new(points + pointIndex) Point();
}
Далее я заполню точкив Java с произвольными числами, основанными на заданных смещениях:
for (int i = 0; i < NUMBER_OF_POINTS; i++) {
unsafe.putDouble(address + i * SIZE_OF_POINT + X_OFFSET, i);
unsafe.putDouble(address + i * SIZE_OF_POINT + Y_OFFSET, i * 2);
}
Далее вызывается public static native void multiplyPoints();
, который только ebe производит каждую секундуint с предыдущим.
Наконец, я напечатаю заданные значения в Java:
for (int i = 0; i < NUMBER_OF_POINTS; i++) {
System.err.print(unsafe.getDouble(address + i * SIZE_OF_POINT + X_OFFSET));
System.err.print(" ; ");
System.err.println(unsafe.getDouble(address + i * SIZE_OF_POINT + Y_OFFSET));
}
Эти этапы на самом деле выводят правильные результаты.
У меня вопрос, если эти этапыразумно: могу ли я предположить, что данные смещения являются правильными (пока на той же машине), и что запись значений непосредственно в буфер в Java и чтение их из объектов в C ++ всегда будут давать правильные результаты?