我正在尝试使用Julia的ccall函数来连接C库.所有类型和指针都是正确的,下面的函数调用成功返回正确的答案(为简洁起见,此处未显示变量定义和设置).
ccall((:vDSP_convD, libacc), Void,
(Ptr{T}, Int64, Ptr{T}, Int64, Ptr{T}, Int64, UInt64, UInt64),
x_padded, 1, pointer(K, Ksize), -1, result, 1, Rsize, Ksize)
Run Code Online (Sandbox Code Playgroud)
但是,如果我希望将函数名称生成为符号,然后将其用作参数ccall,则失败.
fname = symbol(string("vDSP_conv", "D"))
ccall((fname , libacc), Void,
(Ptr{T}, Int64, Ptr{T}, Int64, Ptr{T}, Int64, UInt64, UInt64),
x_padded, 1, pointer(K, Ksize), -1, result, 1, Rsize, Ksize)
Run Code Online (Sandbox Code Playgroud)
错误是:
ERROR: LoadError: TypeError: conv: in ccall: first argument not a
pointer or valid constant expression, expected Ptr{T},
got Tuple{Symbol,ASCIIString}
Run Code Online (Sandbox Code Playgroud)
如果我打印这两个命名版本中的每一个的类型,我得到
julia> println(typeof(:vDSP_convD))
Symbol
julia> println(typeof(fname))
Symbol
Run Code Online (Sandbox Code Playgroud)
有没有办法让这个工作?我猜我必须将它包装在一个宏中或者@eval …
我正在尝试使用StreamWriterApache Arrow 提供的 C++ 类。
唯一的使用示例StreamWriter使用低级 Parquet API,即
parquet::schema::NodeVector fields;
fields.push_back(parquet::schema::PrimitiveNode::Make(
"string_field", parquet::Repetition::OPTIONAL, parquet::Type::BYTE_ARRAY,
parquet::ConvertedType::UTF8));
fields.push_back(parquet::schema::PrimitiveNode::Make(
"char_field", parquet::Repetition::REQUIRED, parquet::Type::FIXED_LEN_BYTE_ARRAY,
parquet::ConvertedType::NONE, 1));
auto node = std::static_pointer_cast<parquet::schema::GroupNode>(
parquet::schema::GroupNode::Make("schema", parquet::Repetition::REQUIRED, fields));
Run Code Online (Sandbox Code Playgroud)
最终结果是 a std::shared_ptr<parquet::schema::GroupNode>,然后可以将其传递到StreamWriter.
是否可以构建和使用“高级”箭头模式StreamWriter?使用该函数(非流式传输)时支持它们WriteTable,但我没有发现它与流式 API 一起使用的示例。
当然,我可以求助于使用低级 API,但在创建大型且复杂的模式时它非常冗长,我更喜欢(但不需要)使用高级 Arrow 模式机制。
例如,
std::shared_ptr<arrow::io::FileOutputStream> outfile_;
PARQUET_ASSIGN_OR_THROW(outfile_, arrow::io::FileOutputStream::Open("test.parquet"));
// construct an arrow schema
auto schema = arrow::schema({arrow::field("field1", arrow::int64()),
arrow::field("field2", arrow::float64()),
arrow::field("field3", arrow::float64())});
// build the writer properties
parquet::WriterProperties::Builder builder;
auto properties = builder.build()
// …Run Code Online (Sandbox Code Playgroud) 我希望有人可以澄清Julia垃圾收集器行为的一个方面,以及它如何与使用C调用C函数分配的内存交互ccall.
例如,我正在进行以下调用:
setup::Ptr{Void} = ccall(("vDSP_DCT_CreateSetup", libacc), Ptr{Void},
(Ptr{Void}, UInt64, UInt64),
previous, length, dct_type)
Run Code Online (Sandbox Code Playgroud)
此函数为DFT_Setup对象分配内存并初始化内存(详细信息无关紧要).DFT_Setup一旦不再需要该对象,该库还提供了在释放内存时调用的析构函数.
在Julia中调用析构函数是否必要?即垃圾收集器是否在DFT_Setup适当时处理释放,或者我应该调用C解除分配器?
我试图将文档字符串与用@eval宏定义的函数相关联;我还希望使用符号来动态生成文档字符串。
for (f, name) in ((:add, :addition), ... )
@eval begin
@doc "Documentation for $name" ->
function f(args)
## FUNCTION BODY
end
end
end
Run Code Online (Sandbox Code Playgroud)
虽然我可以$name从@eval语句中成功引用,但我不能$name从文档字符串本身中引用。它给出了错误UndefVarError: name not defined。
1)有没有办法让它起作用?我尝试了多种方法来摆脱@doc范围并访问周围范围内的变量,但我没有成功。
2)->语法的本质是什么?
我->从 Github获得了语法,但我在 Julia 文档中找不到它的提及,即使使用 Julia 一段时间了,我以前也没有遇到过。