在 Julia 中声明 C void 指针的正确方法 [英] the proper way to declare C void pointers in Julia
问题描述
好吧,我最初把这个问题的表述搞砸了(自从我认真编写 C++ 代码以来已经一年多了,而且我对纯 C 的经验非常有限),所以让我们再试一次.
Ok, I originally badly screwed up my formulation of this question (it's more than a year now since I seriously wrote C++ code and I have pretty limited experience with pure C), so let's try again.
编写一些 C 代码是为了期望您执行以下操作
Some C code is written to expect you to do something like the following
void* p;
create_new_thing(&p); //p is now a new thing
do_stuff_to_thing(p); //something happened to p
我的问题是如何在 Julia 中创建对象 p
.现在我相信答案是
My question is how to create the object p
in Julia. Right now I believe the answer to be
p = Ref{Ptr{Void}}()
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p)
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p)
此外,我相信相同的代码,但将 p
声明为 p = Array(Ptr{Void}, 1)
也可以.
Furthermore, I believe the same code but with p
declared instead as p = Array(Ptr{Void}, 1)
also works.
然而,我确实发现 Julia 中 Ref
和 Ptr
之间的整个区别非常令人困惑,主要是因为它们似乎以我无法跟踪的方式相互转换.
I do however find the whole distinction between Ref
and Ptr
in Julia very confusing, mostly because they seem to get converted between each other in ways I cannot keep track of.
推荐答案
你的代码看起来几乎没问题.不过要小心!任何小错误,例如您在此处遇到的错误,都可能导致分段错误:
Your code looks almost fine. But be careful! Any small error, like the one you have here, can cause a segmentation fault:
p = Ref{Ptr{Void}}()
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p)
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p)
# error here ^
正确的做法是
p = Ref{Ptr{Void}}()
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p)
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p[])
# fixed ^
了解在何处使用p
和p[]
的最简单方法是考虑相应的C 代码.在C中,我们写
The easiest way to understand where to use p
and p[]
is to think of the corresponding C code. In C, we write
void *p;
create_new_thing(&p)
do_stuff_to_thing(p)
Julia 对象不像 C 对象那样具有一流的内存地址,因此我们必须在 Julia 中使用 p = Ref{Ptr{Void}}()
来获取内存地址.这个对象,作为一个引用,行为类似于 C 中的 &p
.这意味着要获取对象本身,在 C 中的 p
,我们需要使用 p[]
在 Julia 中.
Julia objects do not have first-class memory addresses like C objects do, so we must use p = Ref{Ptr{Void}}()
in Julia to get a memory address. This object, as a ref, behaves like &p
in C. That means to get the object itself, p
in C, we need to use p[]
in Julia.
所以 Julia 中的等价物是
So the equivalent in Julia is
p = Ref{Ptr{Void}}() # this p corresponds to &p in C
ccall(:create_new_thing, ..., p) # like &p
ccall(:do_stuff_to_thing, ..., p[]) # like *(&p); that is, like p
这篇关于在 Julia 中声明 C void 指针的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!