简体   繁体   English

从Ruby / Python调用C ++类函数

[英]Calling C++ class functions from Ruby/Python

In my specific circumstance, I have a complex class (a class of classes of classes) that I want to expose to a scripting language (aka Ruby). 在我的特定情况下,我有一个复杂的类(一类类的类)要公开给脚本语言(也就是Ruby)。 Rather that directly pass that complex class, someone gave me the idea of just opening up a few functions to a scripting language like Ruby, which seemed simpler. 与其直接通过复杂的类,不如给我一个想法,就是为Ruby之类的脚本语言打开一些函数,这似乎更简单。 I've seen Rice but the only examples I've seen use simple functions that just multiply something, rather than interfacing with a class. 我看过Rice,但是我看到的唯一示例都使用简单的函数,这些函数只是将某些内容相乘,而不是与类进行交互。

For simplicity, I have a simple class with functions I want to expose: 为简单起见,我有一个简单的类,其中包含要公开的功能:

class Foo
{
    private:
        //Integer Vector:
        std::vector<int> fooVector;

    public:
        //Functions to expose to Ruby:
        void pushBack(const int& newInt) {fooVector.push_back(newInt);}
        int& getInt(const int& element) {return fooVector.at(element);}
};

ALSO: 也:

I'd prefer not to just have a link to the download page of SWIG, or an article explaining how to do this with rice that was written in 2010, I would like a guide that will likely work (I haven't had much luck just yet) 我不想仅链接到SWIG的下载页面,也不希望有一篇介绍如何用2010年编写的大米做文章的文章,我想要一个可能有用的指南(我运气不太好)刚刚)

ASWELL: ASWELL:

I'm using Linux (Ubuntu) but this is a cross-compatible program, so I must be able to compile on Windows and OS X 我正在使用Linux(Ubuntu),但这是一个相互兼容的程序,因此我必须能够在Windows和OS X上进行编译

EDIT: 编辑:

I do understand that shared libraries exist (dll and so files), but I don't know if I can have a library that depends on a .hpp file containing the class(es). 我确实知道共享库(dll等文件)存在,但是我不知道我是否可以拥有一个依赖于包含类的.hpp文件的库。

You can use cython or Boost.Python to call native code from python. 您可以使用cythonBoost.Python从python调用本机代码。 Since you are using c++, i'd recommend looking into Boost.Python which offers a very natural way of wrapping c++ classes for python. 由于您使用的是c ++,因此建议您查看Boost.Python ,它提供了一种非常自然的方法来为python包装c ++类。

As an example (close to what you provided), consider the following class definitions 作为示例(接近您提供的内容),请考虑以下类定义

class Bar
{
private:
    int value;

public:
    Bar() : value(42){ }

    //Functions to expose to Python:
    int getValue() const { return value; }
    void setValue(int newValue) { value = newValue; }
};

class Foo
{
private:
    //Integer Vector:
    std::vector<int> fooVector;
    Bar bar;

public:
    //Functions to expose to Python:
    void pushBack(const int& newInt) { fooVector.push_back(newInt); }
    int getInt(const int& element) { return fooVector.at(element); }
    Bar& getBar() { return bar; }
};

double compute() { return 18.3; }

This can be wrapped to python using Boost.Python 可以使用Boost.Python将其包装到python

#include <boost/python.hpp>
BOOST_PYTHON_MODULE(MyLibrary) {
    using namespace boost::python;

    class_<Foo>("Foo", init<>())
        .def("pushBack", &Foo::pushBack, (arg("newInt")))
        .def("getInt", &Foo::getInt, (arg("element")))
        .def("getBar", &Foo::getBar, return_value_policy<reference_existing_object>())
    ;

    class_<Bar>("Bar", init<>())
        .def("getValue", &Bar::getValue)
        .def("setValue", &Bar::setValue, (arg("newValue")))
    ;

    def("compute", compute);
}

This code can be compiled to a static library MyLibrary.pyd and used like this 可以将此代码编译到静态库MyLibrary.pyd并像这样使用

import MyLibrary

foo = MyLibrary.Foo()
foo.pushBack(10);
foo.pushBack(20);
foo.pushBack(30);
print(foo.getInt(0)) # 10
print(foo.getInt(1)) # 20
print(foo.getInt(2)) # 30

bar = foo.getBar()
print(bar.getValue()) # 42
bar.setValue(17)
print(foo.getBar().getValue()) #17

print(MyLibrary.compute()) # 18.3

What about Boost.Python ? 那么Boost.Python呢?

How come you don't want to use SWIG? 您为什么不想使用SWIG?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM