SimipleCTypes.jl is a zero-dependency Julia package that provides some simple definitions of C types, specifically:
CfuncPtrfor C function pointersCarrayfor fixed-size C arraysCunionfor C-style unions
It is mainly used in the type definitions of Julia bindings for C libraries. All types are immutable so that they can have the same memory layout as in C.
CfuncPtr can be used to replace Ptr{Cvoid} in ccall and struct definitions,
so that you can pass a function pointer around in a type-safe way.
It takes two type parameters, the return type and the argument types of the function.
struct foo {
int (*f)(int, int);
};can be defined in Julia as:
struct Foo
f::CfuncPtr{Cint,Tuple{Cint,Cint}}
endYou can use @cfunc to create a CfuncPtr from a Julia function,
its usage is the same as @cfunction:
f(x) = 2x
fptr, _ = @cfunc(f, Cint, (Cint,))
fptr2, cf = @cfunc($f, Cint, (Cint,))When using a clousure, you need to use $ to interpolate the function into the macro,
and the second return value of @cfunc (cf in the example) should be referenced somewhere
to prevent the GC from collecting it.
Carray is similar to StaticArrays.SArray, representing a fixed-size immutable array.
Usually you only need to use @Carray whenever you need a C array. For example,
int[3] a = {1,2,3};
struct bar {
double x[2][4];
};can be defined in Julia as:
a = @Carray(Cint[1,2,3])
struct Bar
x::@Carray{Cdouble,2,4}
endNote that the array will be stored in row-major order, so when you pass a Julia array to @Carray, the dimension order is reversed.
Cunion represents a C-style union. You need to use @Cunion begin ... end to declare a union type.
For example,
union Baz {
union {
uint64_t x;
unsigned char y[8];
} a;
uint b[2];
} baz = { .a = { .x = 0x123456789abcdef0 } };should be:
const Baz = @Cunion begin
a::@Cunion begin
x::Cuint64
y::@Carray{Cuchar,8}
end
b::Carray{Cuint,2}
end
baz = Baz(a=(; x=0x123456789abcdef0))And the usage of baz is almost the same as in C, except that Cunions and Carrays are all immutable.