gpt4 book ai didi

c - Julia - 具有非基本类型的 C 接口(interface)

转载 作者:太空狗 更新时间:2023-10-29 15:05:24 25 4
gpt4 key购买 nike

我正在扩展一个使用 C 库的 Julia 包。我需要从 Julia 调用一些 C 函数。它们看起来像这样:

struct contained {
int x;
int y;
int z;
};
struct mystruct {
int n;
contained* arr;
};
mystruct* mk_mystruct(int n, contained* arr);
void use_mystruct(mystruct* foo);

我也在 Julia 中声明了相应的类型:

type contained
x::Int64
y::Int64
z::Int64
end
type mystruct
n::Int64
arr::Array{contained, 1}
end

对于以 contained* 作为参数的 ccall 函数,一切正常,将 contained* 视为 Ptr{Int64 :

con = fill(0, 5, 3);
mys = ccall((:mk_mystruct, "mylib"), Ptr{mystruct}, (Int64, Ptr{Int64}), n, con)

我想这是可行的,因为 contained 具有与 Int64 数组相同的内存布局。这也是 Julia 包中其他地方的做法。但我知道检查返回的 mystruct 值的唯一方法是使用 unsafe_load 取消引用它,此时 Julia 因段错误而崩溃。在 Julia 中取消引用指针的正确方法是什么?

C 库还包含 pretty-print 函数,因此我可以将指针视为不透明的,而不是在 Julia 中取消引用指针并将其传递回此 C 函数:

void print_mystruct(mystruct* foo, FILE* outputfile)

在 C 代码中,这是用 outputfile=stdout 调用的。我将如何使用 ccall 进行设置?这显然行不通:

ccall((:print_mystruct, "mylib"), Void, (Ptr{mystruct}, Ptr{Void}), mys, stdout)

我应该用什么代替 Ptr{Void}stdout? Julia是如何在C接口(interface)中实现I/O的?

最佳答案

在 Julia 中声明类型时,必须声明与 C 相同的类型:

type contained
x::Cint
y::Cint
z::Cint
end
type mystruct
n::Cint
arr::Ptr{contained}
end

Julia 类型 Array{contained, 1} 对应于 C 中的 jl_value_t* 而 Julia 类型 Int 对应于 C 中的 >intptr_t

我不知道有什么平台不可知的方法来获取 stdout 的句柄,因为大多数平台都需要扩展 C 头宏来找出真正的符号名称。例如,在 macOS 上,它被重命名为 __stdoutp:

julia> unsafe_load(cglobal(:__stdoutp, Ptr{Void}))
Ptr{Void} @0x00007fff751f7348

julia> ccall(:fprintf, Csize_t, (Ptr{Void}, Cstring, Cint...), ans, "hi\n")
hi
0x0000000000000003

您可能有兴趣查看 Clang.jl package它可以通过解析头文件自动生成这些定义。

关于c - Julia - 具有非基本类型的 C 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39729347/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com