我遇到了一个奇怪的问题,即我与共享库连接时,当我尝试使用ccall
时会遇到段错误。我已经用Python重写了代码,但是没有任何问题。它也仅在GC.enable(true)
时发生。如果我在运行任何GC.enable(false)
函数之前先运行ccall
,则一切正常。
奇怪的是,当我运行以下命令时:
GC.enable(false)
var1 = Ref(...)
var2 = pointer(...)
ccall(...)
GC.enable(true)
它仍然存在段错误。
我在此GitHub link上发布了一个最小的工作示例。我希望有人可以看看并告诉我我做错了什么?
此外,如果有人可以在使用C中的不同类型的模式时在Julia中使用ccall时提供最佳实践建议,那将非常有用。目前,我所获得的最多信息是官方文档,该文档很有用,但并不涵盖我与C代码交互时看到的所有模式。
答案 0 :(得分:3)
您可以使用GC.@preserve
来临时防止变量被垃圾回收:
var1
var2
GC.@preserve var1 var2 begin
ccall(...)
var3 = unsafe_xxx
end
var3
真正的原因是您的共享库需要ResultPtr
才能正确初始化,而您刚遇到一些未定义的行为:
julia> Ref{Ptr{Cstring}}(C_NULL)
Base.RefValue{Ptr{Cstring}}(Ptr{Cstring} @0x0000000000000000)
julia> Ref{Ptr{Cstring}}()
Base.RefValue{Ptr{Cstring}}(Ptr{Cstring} @0x000000011b98ca70) # this results in segfaults
➜ opendss-debug git:(master) ✗ julia -e '@show Ref{Ptr{Cstring}}()'
Ref{Ptr{Cstring}}() = Base.RefValue{Ptr{Cstring}}(Ptr{Cstring} @0x0000000000000000)