【发布时间】:2015-09-16 17:24:03
【问题描述】:
我无法从 Julia 调用 C 函数。这可能是一个普遍有用的问题,但我将在我正在努力解决的具体环境中描述它。我正在尝试创建一个bson 对象:
BSONObject("{a:1}")
所以这个对象的构造函数被调用:
BSONObject(jsonString::String) = begin
jsonCStr = bytestring(jsonString)
bsonError = BSONError()
_wrap_ = ccall(
(:bson_new_from_json, libbson),
Ptr{Void}, (Ptr{Uint8}, Csize_t, Ptr{Uint8}),
jsonCStr,
length(jsonCStr),
bsonError._wrap_
)
_wrap_ != C_NULL || error(bsonError)
bsonObject = new(_wrap_, None)
finalizer(bsonObject, destroy)
return bsonObject
end
在https://github.com/pzion/LibBSON.jl/blob/master/src/BSONObject.jlLibBSON 包中需要处理MongoDB 查询,但设置不是特别重要。重要的是ccall,它传递一个字符串jsonCStr、这个字符串的长度和bsonError._wrap_。最后一个对象来自https://github.com/pzion/LibBSON.jl/blob/master/src/BSONError.jl,是一个数组:
type BSONError
_wrap_::Vector{Uint8}
function BSONError()
return new(Array(Uint8, 512))
end
end
在BSONError对象的上述构造函数中创建了一个512个Uint8的数组。这个 Julia bsonError._wrap_ 在 C 中引用了以下 struct:
typedef struct
{
uint32_t domain;
uint32_t code;
char message[504];
} bson_error_t;
参见http://api.mongodb.org/libbson/current/bson_error_t.html,这个结构的长度是 4 + 4 + 504 = 512,所以看起来没问题。
现在回到ccall,它的类型签名是Ok:Ptr{Uint8}指向字符串,Csize_t是它的大小类型,Ptr{Uint8}指向struct。但是,后者返回错误消息:
LoadError: MethodError: `convert` has no method matching convert(::Type{Ptr{UInt8}}, ::Array{UInt8,1})
This may have arisen from a call to the constructor Ptr{UInt8}(...),
since type constructors fall back to convert methods.
Closest candidates are:
call{T}(::Type{T}, ::Any)
convert{T<:Union{Int8,UInt8}}(::Type{Ptr{T<:Union{Int8,UInt8}}}, !Matched::Cstring)
convert{T}(::Type{Ptr{T}}, !Matched::UInt64)
...
while loading In[2], in expression starting on line 1
in convert at /Users/szalmaf/.julia/v0.4/LibBSON/src/BSONError.jl:21
in call at /Users/szalmaf/.julia/v0.4/LibBSON/src/BSONObject.jl:33
显然,试图将Array 转换为Ptr{UInt8} 类型。
Julia 手册 http://julia.readthedocs.org/en/latest/manual/calling-c-and-fortran-code/#mapping-c-types-to-julia 在“将 C 类型映射到 Julia”部分的“位类型”小节中说 Julia Array{T,N} 应该作为 Ptr{T} 传递,在这种情况下 T 是 UInt8 .所以 Julia ccall 看起来不错,但仍然有该错误消息。这是一个非常紧迫的问题,因为它阻止了数据库中更复杂的查询。关于如何解决这个ccall 问题的任何建议?
附:请注意,如果您安装了 LibBSON 包和 libbson C 库附带的 Mongo 包。
【问题讨论】:
-
我刚刚在 BSONError.js 中发现了一个导致问题的错误,我正在写一个答案。我认为它与版本无关。
标签: c arrays pointers struct julia