我用到的C的结构体定义如下:
typedef struct t_HDataField {
char field_name[32]; //字段名
int field_type; //字段类型
int field_op;
int field_size; //字段长度
int field_flags;
} HDataField;
typedef struct t_HDataType {
char type[32];
int field_count; /// 字段数量
HDataField fields[512]; /// 字段定义数组
int data_size; /// 数据类型长度,即所有字段长度的和
} HDataType;
typedef struct t_HDataItem {
char symbol[24]; /// 标的代码
int index; /// 索引
int trading_day; /// 日期
int64_t local_time; /// Unix时间
int time_point_seq_no; ///序号
int type_id; /// 数据类型id
const uint8_t* data; /// 指向数据内容的指针
} HDataItem;
typedef struct t_HCodeInfo {
char symbol[24]; /// 标的代码
int index; /// 索引
int total_items_num; /// 该代码在数据文件中总记录数
int type_items_nums[24]; /// 该代码在数据文件中每种数据类型的记录数
const uint8_t* data; /// 指向代码信息内容的指针(可能为空指针)
} HCodeInfo;
我想调用的dll中的函数如下:
* 打开给定路径的数据库文件。
*
* @param db_id 数据库句柄
* @param path 文件路径,即相对于根目录的文件相对路径
* @param ci_type 代码信息数据类型定义,输出参数。
* @param data_types 数据类型定义数组,输出参数。
* @param count 数据类型定义数量。
* 输入时为输入的data_types数组长度,输出为返回的数据类型数量。
* 若输入时该值比需要返回的数量小时,接口返回HRetCode_NotEnoughMemory
*
* @return 成功返回HDB文件句柄,失败返回0
*/
uint64_t hdb_open_file(uint64_t db_id, const char* path, int flags,
HDataType* ci_type, HDataType* data_types,
int* count);
我把它们按如下方式在julia里面定义好了,
struct HDataField
field_name::NTuple{32, Char}
field_type::Cint
field_op::Cint
field_size::Cint
field_flags::Cint
end
struct HDataType
type::NTuple{32, Char}
field_count::Cint
fields::NTuple{512,HDataField}
data_size::Cint
end
struct HDataItem
symbol::NTuple{24, Char}
index::Cint
trading_day::Cint
local_time::Int64
time_point_seq_no::Cint
type_id::Cint
data::Ptr{UInt8}
end
struct HCodeInfo
symbol::NTuple{24,Char}
index::Cint
total_items_num::Cint
type_items_nums::NTuple{64,Cint}
data::Ptr{UInt8}
end
并打算按如下方式用julia的ccall来调用:
hdb_open_file = Libdl.dlsym(lib, :hdb_open_file)
db = 162994
md_types = Vector{HDataType}(undef, 16)
type_num = 16
ci_type = md_types[0]
md_type_r = Ref(md_types)
type_num_r = Ref(type_num)
ci_type_r = Ref(type_num)
fileid = ccall(hdb_open_file, UInt64, (UInt64, Ptr{UInt8}, Cint, Ref{HDataType},
Ref{HDataType}, Ref{Cint}), Int(db),
"marketdata/tick_20201225", 0, ci_type_r, md_type_r, type_num_r)
结果运行后报错如下:
ERROR: MethodError: Cannot `convert` an object of type Base.RefValue{Vector{HDataType}} to an object of type HDataType
Closest candidates are:
convert(::Type{T}, ::T) where T at C:\Users\linan\AppData\Local\Programs\Julia-1.7.2\share\julia\base\essentials.jl:218
HDataType(::Any, ::Any, ::Any, ::Any) at REPL[58]:2
Stacktrace:
[1] Base.RefValue{HDataType}(x::Base.RefValue{Vector{HDataType}})
@ Base .\refvalue.jl:8
[2] convert(#unused#::Type{Ref{HDataType}}, x::Base.RefValue{Vector{HDataType}})
@ Base .\refpointer.jl:104
[3] cconvert(T::Type, x::Base.RefValue{Vector{HDataType}})
@ Base .\essentials.jl:417
[4] top-level scope
@ .\REPL[85]:1
问题究竟出在哪里? 跪求高手过来看看