调用C++;具有std::vectors作为Julia的输入和输出参数的函数 我是朱丽亚的新手,我正在尝试访问朱丽亚的C++代码。更确切地说,我试图用CXX调用朱丽亚的C++函数。C++函数的输入和输出参数是STD::向量,参见下面例子中的函数CopyTeIt和: #include <vector> #include <iostream> std::vector< int > compute_sum( const std::vector< std::vector<int> >& input ) { std::vector< int > resut( input.size() , 0 ); for ( std::size_t i = 0 ; i != input.size() ; ++i ) { for ( std::size_t j = 0 ; j != input[i].size() ; ++j ) { resut[i] += input[i][j]; } } return resut; } void simple_function( int i ) { std::cout << "The numbers is : " << i << std::endl; }
因此,我获得了一个文件代码 有了这个,我在与code.so相同的文件夹中运行Julia。我的Julia版本是0.6.2。然后,我使用以下方法导入Cxx和code.so文件:调用C++;具有std::vectors作为Julia的输入和输出参数的函数 我是朱丽亚的新手,我正在尝试访问朱丽亚的C++代码。更确切地说,我试图用CXX调用朱丽亚的C++函数。C++函数的输入和输出参数是STD::向量,参见下面例子中的函数CopyTeIt和: #include <vector> #include <iostream> std::vector< int > compute_sum( const std::vector< std::vector<int> >& input ) { std::vector< int > resut( input.size() , 0 ); for ( std::size_t i = 0 ; i != input.size() ; ++i ) { for ( std::size_t j = 0 ; j != input[i].size() ; ++j ) { resut[i] += input[i][j]; } } return resut; } void simple_function( int i ) { std::cout << "The numbers is : " << i << std::endl; },c++,julia,std,C++,Julia,Std,因此,我获得了一个文件代码 有了这个,我在与code.so相同的文件夹中运行Julia。我的Julia版本是0.6.2。然后,我使用以下方法导入Cxx和code.so文件: julia> using Cxx julia> const path_to_lib = pwd() julia> addHeaderDir(path_to_lib, kind=C_System) julia> Libdl.dlopen(path_to_lib * "/code.so", Libdl.R
julia> using Cxx
julia> const path_to_lib = pwd()
julia> addHeaderDir(path_to_lib, kind=C_System)
julia> Libdl.dlopen(path_to_lib * "/code.so", Libdl.RTLD_GLOBAL)
Ptr{Void} @0x00000000044bda30
julia> cxxinclude("code.cpp")
为了测试该过程是否成功,我调用了simple_函数并获得了正确的结果:
julia> @cxx simple_function(1234)
The numbers is : 1234
然后我想调用compute_sum函数。为此,我需要创建或将朱丽亚向量转换成C++ STD::vector < STD::vector >。我正在尝试以下方法:
julia> cxx" std::vector< std::vector<int> > a;"
true
julia> icxx" a.push_back( std::vector<int>(1,2) ); "
julia> icxx" a.push_back( std::vector<int>(1,3) ); "
julia> icxx" a.push_back( std::vector<int>(1,4) ); "
julia> icxx" a.size(); "
0x0000000000000003
有人能帮我回答以下问题吗
pawel因为您愿意研究Julia数组,所以我假设您希望研究矩阵,即维中具有恒定长度的数组。因此,我建议您不要使用
vector
s的vector
s,而只使用vector
s。然后,您应该记住Julia使用列主数组,而在C/C++中,内存布局是行主数组
在下面,您可以使用迭代器找到代码的模板版本。这样,你就可以编译<代码> CopyTeTeaSoG/<代码>,供C++使用,并使用你喜欢的<代码> STD::向量< /代码>或者,您可以要求编译器生成带有指针的适当代码,以便能够与其他语言(如Julia)一起使用
#包括
#包括
#包括
模板
输出计算和(常数std::uint64\u t nrows、RandomIt xbegin、RandomIt xend、,
输出(贝金){
常数std::size\u t ncols{std::distance(xbegin,xend)/nrows};
typename std::迭代器\特征::值\类型和{0};
对于(std::size\u t row=0;row
然后,像往常一样编译代码:
g++-Wall-std=c++11-O3-fPIC-shared code.cpp-o code.so
然后,使用Julia调用已编译的C代码:
const libhandle = Libdl.dlopen(joinpath(pwd(), "code.so"))
const funhandle = Libdl.dlsym(libhandle, :compute_sum)
function compute_sum(A::Matrix{Int64})
result = Vector{Int64}(size(A, 1))
ccall(funhandle, Void, (UInt64, UInt64, Ref{Int64}, Ref{Int64}),
size(A, 1), size(A, 2), A, result)
return result
end
result = compute_sum(ones(Int64, 5, 6)) # prints Int64[6, 6, 6, 6, 6]
我希望这有帮助。干杯 诀窍是使用
icxx
string宏,这允许使用$
插值Julia变量。以下是一个完整的示例:
using Cxx
cxx"""
#include <iostream>
#include <vector>
std::vector<int> compute_sum(const std::vector<std::vector<int>> &input)
{
std::vector<int> result(input.size(), 0);
for (std::size_t i = 0; i != input.size(); ++i)
{
for (std::size_t j = 0; j != input[i].size(); ++j) // corrected to ++j here
{
result[i] += input[i][j];
}
}
return result;
}
"""
cxx_v = icxx"std::vector<std::vector<int>>{{1,2},{1,2,3}};"
println("Input vectors:")
for v in cxx_v
println(" ", collect(v))
end
cxx_sum = icxx"compute_sum($cxx_v);"
println("Cxx sums: $(collect(cxx_sum))")
要使用共享库执行此操作,请按如下方式创建vector.hpp
:
#include <vector>
std::vector<int> compute_sum(const std::vector<std::vector<int>> &input);
汇编:
g++ -shared -fPIC -o libvector.so vector.cpp
在朱莉娅:
using Cxx
const path_to_lib = pwd()
addHeaderDir(path_to_lib, kind=C_System)
Libdl.dlopen(joinpath(path_to_lib, "libvector"), Libdl.RTLD_GLOBAL)
cxxinclude("vector.hpp")
cxx_v = icxx"std::vector<std::vector<int>>{{1,2},{1,2,3}};"
println("Input vectors:")
for v in cxx_v
println(" ", collect(v))
end
cxx_sum = icxx"compute_sum($cxx_v);"
println("Cxx sums: $(collect(cxx_sum))")
使用Cxx
const path_to_lib=pwd()
addHeaderDir(路径到库,种类=C系统)
Libdl.dlopen(joinpath(path_to_lib,“libvector”),Libdl.RTLD_GLOBAL)
cxxinclude(“vector.hpp”)
cxx_v=icxx“std::vector{{1,2},{1,2,3};”
println(“输入向量:”)
对于cxx_v中的v
println(“,collect(v))
结束
cxx_sum=icxx“计算总和($cxx_v);”
println(“Cxx总和:$(收集(Cxx_总和)))
我要感谢Arda Aytekin和Bart Janssens的大力帮助和建议。两种解决方案都非常有效,我想将它们都标记为我问题的答案,但似乎我只能标记一个答案…在接下来的几天里,我将运行速度比较测试,看看基于纯C接口的解决方案是否比使用Cxx的解决方案更快。一旦准备好了,我会给你更新 “我正在使用:
g++-shared-fPIC code.cpp-o代码将它编译成一个静态库。因此
”-这里有些混乱。您说您构建了一个静态库,但-shared
编译器选项则相反。此外,静态库通常用“.a”扩展名命名,而“.so”表示共享库(“so”是“共享对象”的缩写)。那么,你到底想做什么?谢谢你指出,我的意思是共享对象。将行更改为:“我正在将其编译为共享目标代码。因此使用”。希望现在更清楚。你用这个做什么?它是像矩阵的行和,还是输入
中的向量
s允许有不同的大小
s?另外,您的代码中似乎有一个小故障——内部循环也在增加i
。这是有意的吗?非常感谢!这当然有助于我树立榜样,谢谢你的帮助。我还有一个问题。当函数compute_sum在Julia中给出时,此解有效。然而,当我试图从预编译的共享对象调用函数时,我得到了一个分段错误:julia>icxx“compute_sum($cxx_v);”信号(11):在第0行未知函数(ip:0x7f4fa27de7d9)开始的表达式中,没有加载文件时出现分段错误(ip:0x7f4fa27de7d9)未知函数(ip:0x7f4fa27de6db)未知函数(ip:0x7f4fa27de6bc)您知道这是否可以修复吗?我已经更新了答案,您需要一个单独的标题,并确保将第二个++I更改为
#include <vector>
std::vector<int> compute_sum(const std::vector<std::vector<int>> &input);
#include "vector.hpp"
std::vector<int> compute_sum(const std::vector<std::vector<int>> &input)
{
// same as before
}
g++ -shared -fPIC -o libvector.so vector.cpp
using Cxx
const path_to_lib = pwd()
addHeaderDir(path_to_lib, kind=C_System)
Libdl.dlopen(joinpath(path_to_lib, "libvector"), Libdl.RTLD_GLOBAL)
cxxinclude("vector.hpp")
cxx_v = icxx"std::vector<std::vector<int>>{{1,2},{1,2,3}};"
println("Input vectors:")
for v in cxx_v
println(" ", collect(v))
end
cxx_sum = icxx"compute_sum($cxx_v);"
println("Cxx sums: $(collect(cxx_sum))")