调用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++;具有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

因此,我获得了一个文件代码

有了这个,我在与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.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
有人能帮我回答以下问题吗

  • 如何从Julia调用compute_sum函数?我很乐意使用任何有效且速度相当快的技术(不需要Cxx)
  • 如何将计算结果转换为Julia数组
  • 多谢各位


    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))")