我想调用的C函数长这样:
# * 获取指定时间段的指数历史Tick数据,接口支持单个代码或多个代码组合获取数据。
# *
# * @param symbol_list 指数代码列表,以逗号分开的市场.证券代码,如"sh.000001,sz.399992"
# * @param begin_time 开始时间,YYYY/MM/DD hh:mm:ss,如"2017/07/05 9:0:0"
# * @param end_time 结束时间,YYYY/MM/DD hh:mm:ss,如"2017/07/05 10:0:0"
# * @param itd 获取的指数tick数据
# * @param count 获取的数据个数
# * @return 成功返回0,失败返回错误码
int get_index_ticks(const char* symbol_list, const char* begin_time,
const char* end_time, IndexTickData** itd,
int* count);
其中IndexTickData是一个结构体:
#pragma pack(push, 1)
typedef struct t_IndexTickData{
char symbol[12];
int32_t time;
int32_t open;
int32_t high;
int32_t low;
int32_t match;
int64_t volume;
int64_t turnover;
int32_t pre_close;
} IndexTickData;
#pragma pack(pop)
这个函数中,整数型的count和指针的指针IndexTickData** 都是作为出参传递进去的,之所以使用指针的指针,是因为在调用之前没法事先预知会有多少条IndexTickData的数据,这个长度是不固定的。调用后会返回IndexTickData的数量,以及一个指针的指针IndexTickData**。通过这两个量就可以解析出全部的数据。我现在如果要在julia中调用这个函数,我能得到正确结果的方式如下:
using CBinding
c``
c""";
#pragma pack(push, 1)
typedef struct t_IndexTickData{
char symbol[12];
int32_t time;
int32_t open;
int32_t high;
int32_t low;
int32_t match;
int64_t volume;
int64_t turnover;
int32_t pre_close;
} IndexTickData;
#pragma pack(pop)
"""
symbol_list = "SZ.000001,SH.600000"
len = Ref{Cint}()
begin_time = "2021/09/16 9:0:0"
end_time = "2021/09/16 15:0:0"
#第一调用不知道定义多大的Vector合适,只能随便输入一个10
std =Vector{Cptr{c"SecurityTickData"}}(undef,10)
err = ccall((:get_index_ticks, lib), Int32, (Ptr{UInt8}, Ptr{UInt8}, Ptr{UInt8}, Cptr{Cptr{c"IndexTickData"}}, Ptr{Cint}), symbol_list, begin_time, end_time, std, len)
#调用后我通过len.x知道了数据条数,就可以根据它正确分配Vector的大小
std =Vector{Cptr{c"SecurityTickData"}}(undef,len.x)
err = ccall((:get_index_ticks, lib), Int32, (Ptr{UInt8}, Ptr{UInt8}, Ptr{UInt8}, Cptr{Cptr{c"IndexTickData"}}, Ptr{Cint}), symbol_list, begin_time, end_time, std, len)
这种方式有个问题,就是要调用两次,不够高效,不够优雅。有没有什么办法一次调用解决这个问题呢?