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")

Reply via email to