Following a previous question of mine, and Some Name's response , I would like to try the opposite way and enhance the previous question:
I would like to do the following steps:
- Allocate buffer in Java
- Fill the array in C++
- Edit the values in Java
- Do some number crunching in C++
- Read the values in Java
Consider the following class in 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)
The following code snippet:
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;
shows the following result:
Size of Point: 24
Address is: 000000D45B0FF2C0
x address is: 000000D45B0FF2C8 and offset is: 8
y address is: 000000D45B0FF2D0 and offset is: 16
So now I can assume the following sizes in Java:
final int NUMBER_OF_POINTS = 10;
final int SIZE_OF_POINT = 24;
final int X_OFFSET = 8;
final int Y_OFFSET = 16;
Next, I will allocate a memory region using unsafe and call public static native void allocatePoints(long address, int numberOfPoints); In order to fill them with Point objects:
long address = unsafe.allocateMemory(NUMBER_OF_POINTS * SIZE_OF_POINT);
allocatePoints(address, NUMBER_OF_POINTS);
The C++ code that fills the points:
Point * points = (Point *) address;
for (int pointIndex = 0; pointIndex < numberOfPoints; pointIndex++) {
new(points + pointIndex) Point();
}
Next, I will fill the points in Java with arbitrary numbers, base on the given offsets:
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);
}
Next, calling public static native void multiplyPoints(); which only ebe products each second point with the one before it.
Finally, I will print the given values in 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));
}
These stages actually prints correct results.
My question is if these stages are reasonable: Can I assume that the given offsets are correct (on the same machine for now), and that writing the values directly into the buffer in Java, and reading them from the objects in C++, will always yield correct results?