The Julia manual says that if you use &x with a ccall expecting a pointer,
then changes to the pointed-to data are not reflected in x upon return.
Essentially, it implies that &x actually passes a pointer to a copy of the
data in x. The usual workaround, if you want to receive the changed value
in Julia, is to pass a 1-element array.
However:
* Experimentally, if you have a mutable type and are passing it for a
struct pointer, then changes to the data *are* returned to Julia. See
below example (tested in MacOS and Linux).
* The array workaround does not work for non-immutable types. For a
mutable type T, my understanding is that an array T[...] is stored as an
array of jl_value_t* pointers, which is inequivalent to an array of C
structs.
Should this (nice?) behavior of & for mutable types be documented? If
not, is there any other way to modify such a type with a C function
expecting a struct pointer?
--SGJ
Example C code:
typedef struct {
double a, b;
} foo;
void init_foo(foo *f) {
f->a = 1.234;
f->b = 5.678;
}
Example Julia code:
# this "works" on Mac and Linux: x is changed to Foo(1.234,5.678):
type Foo
a::Float64
b::Float64
end
x = Foo(0.,0.)
ccall((:init_foo,"sp"), Void, (Ptr{Foo},), &x)
println("x = $x")
# this "works" on Linux (y is changed) but "doesn't work" on Mac (y remains
Bar(0,0)):
immutable Bar
a::Float64
b::Float64
end
y = Bar(0.,0.)
ccall((:init_foo,"sp"), Void, (Ptr{Bar},), &y)
println("y = $y")