Using CxxWrap.jl, I am trying to send a pointer to struct to C++ functions, which will modify the values inside. I did small experiments.
C++ side:
#include "jlcxx/jlcxx.hpp"
struct Point{
float x, y;
};
Point* move(Point* a, int amount) {
a->x += amount;
a->y += amount;
return a;
}
void test() {
Point a;
a.x = 1.0f;
a.y = 2.0f;
Point* b;
b = move(&a, 100);
printf("[test] a = %f, %f\n", a.x, a.y);
printf("[test] b = %f, %f\n", b->x, b->y);
}
JLCXX_MODULE define_julia_module(jlcxx::Module& mod)
{
mod.map_type<Point>("Point");
mod.method("move", move);
mod.method("test", test);
}
The move()
function was intended as a void
type, but it returns the pointer for this experiment.
Julia side:
module MyTypes
using CxxWrap
using Test
struct Point
x :: Float32
y :: Float32
end
@wrapmodule joinpath(@__DIR__, "lib", "libmytypes")
function __init__()
@initcxx
end
end
Experiment 1
MyTypes.test()
The output is
[test] a = 101.000000, 102.000000
[test] b = 101.000000, 102.000000
Both a
and b
changed, as intended.
Experiment 2
When I pass a struct from Julia, I see a
did NOT change, but b
changed.
a = MyTypes.Point(1.0, 2.0)
b = MyTypes.move(Ref(a), 100)
bb = unsafe_load(b)
@show a.x, a.y
@show bb.x, bb.y
Output:
(a.x, a.y) = (1.0f0, 2.0f0)
(bb.x, bb.y) = (101.0f0, 102.0f0)
Experiment 3
If I pass an array of struct, instead of Ref(a)
, then both values changed.
c = [a]
d = MyTypes.move(c, 100)
@show c[1].x, c[1].y
dd = unsafe_load(d)
@show dd.x, dd.y
Output:
((c[1]).x, (c[1]).y) = (101.0f0, 102.0f0)
(dd.x, dd.y) = (101.0f0, 102.0f0)
Why doesn’t Experiment 2 change the values in a
? Shouldn’t it change the values in a
?