Zach
Zach

Reputation: 4792

Returning C structs by-value to Julia

I am trying to pass a C struct to Julia using ccall

Here is my file in C:

#include <stdio.h>

typedef struct {
    float a;
    float b;
} TestStruct;

TestStruct getStruct() {
    TestStruct s = {3.0f, 5.0f};
    printf("Created struct a: %f b: %f\n", s.a, s.b);
    return s;
}

Then I compile this into a shared library to use with Julia.

Here is my Julia file:

immutable TestStruct
    a::Cfloat
    b::Cfloat
end

struct = ccall((:getStruct, "libteststruct"), TestStruct, ())
println("Got struct a: ", struct.a, " b: ", struct.b)

When I run this file I would expect to get

Created struct a: 3.000000 b: 5.000000
Got struct a: 3.0 b: 5.0

However, I am instead getting

Created struct a: 3.000000 b: 5.000000
Got struct a: 3.0 b: 0.0

a is always correct but b is always 0.

This works when I use doubles in the struct instead of floats, but I need to use floats.

Thank you.

Upvotes: 6

Views: 691

Answers (2)

Isaiah Norton
Isaiah Norton

Reputation: 4366

This works fine for me on Julia master (0.4-dev) -- on Windows to boot. Full by-value struct support was only recently merged into master. It might appear to (kind of) work on 0.3 but is not officially supported and should probably be an error.

Upvotes: 5

StefanKarpinski
StefanKarpinski

Reputation: 33259

If you are on Julia v0.3.x, ccall does not handle returning structs via the calling convention correctly. You can try changing the ccall usage to this:

struct_buffer = Array(TestStruct)
ccall((:getStruct, "libteststruct"), Void, (Ptr{TestStruct},), struct_buffer)
struct = struct_buffer[]

This issue may be fixed on Julia master (0.4-dev), so you can also try that and see how it goes.

Upvotes: 4

Related Questions