English 中文(简体)
将C++级班级评为穿透镜
原标题:Exposing a C++ class instance to a python embedded interpreter

我正在寻求一种简单的方式,使C++级班级的口译接触到一名植根口译员。

  • I have a C++ library. This library is wrapped (using swig for the moment) and I am able to use it from the python interpreter
  • I have a C++ main program which instanciates a Foo class from my library and embeds a python interpreter

我愿向世人介绍我的C++世界 F节(并被视为Foo阶级)。

www.un.org/Depts/DGACM/index_spanish.htm 如果是的话,这是否可行?

I think it s almost like in the first answer of : boost::python::ptr or PyInstance_New usage

www.un.org/Depts/DGACM/index_spanish.htm 我认为这意味着我应当使用<条码>boost。 页: 1

我的唯一目标是将我的C++“Foo”案例在嵌入的假肢中加以操纵(但不能确保能够采用先前的方法)。

事实上,我已经把我的Foo阶级暴露在 p(有wi)。

www.un.org/Depts/DGACM/index_spanish.htm 我拥有:

my> oo类:

class Foo{...};

www.un.org/Depts/DGACM/index_chinese.htm

import my_module
foo=my_modulde.Foo()

What I want:

有一个C++主要方案,吸收了一名假肢译员,操纵C++世界变量。

int main(int argc, char **argv)
{
    Foo  foo;   // instanciates foo
    
    Py_Initialize();

    Py_Main(argc, argv); // starts the python interpreter
                         // and manipulates THE foo instance in it

    Py_Finalize();
    
    return 0;
}
最佳回答

Boost python 允许你以非常紧密的综合方式向C++级课堂揭开,你甚至可以总结这些班子,以便你能够从第++号课桌上获得素材,并且将虚拟方法压倒在花板上。

http://www.boost.org/doc/libs/release/libs/python/doc/tutorial/doc/html/index.html“rel=“noreferer”>boost python tutorial 这是一个良好的开端。


edit:

您可创建一套正文,并向内部传译员推荐:

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/python.hpp>
#include <string>
#include <iostream>

namespace bp = boost::python;

struct Foo{
    Foo(){}
    Foo(std::string const& s) : m_string(s){}
    void doSomething() {
        std::cout << "Foo:" << m_string << std::endl;
    }
    std::string m_string;
};

typedef boost::shared_ptr<Foo> foo_ptr;

BOOST_PYTHON_MODULE(hello)
{
    bp::class_<Foo, foo_ptr>("Foo")
        .def("doSomething", &Foo::doSomething)
    ;
};

int main(int argc, char **argv)
{
    Py_Initialize();
    try {
        PyRun_SimpleString(
            "a_foo = None
"
            "
"
            "def setup(a_foo_from_cxx):
"
            "    print  setup called with , a_foo_from_cxx
"
            "    global a_foo
"
            "    a_foo = a_foo_from_cxx
"
            "
"
            "def run():
"
            "    a_foo.doSomething()
"
            "
"
            "print  main module loaded 
"
        );

        foo_ptr a_cxx_foo = boost::make_shared<Foo>("c++");

        inithello();
        bp::object main = bp::object(bp::handle<>(bp::borrowed(
            PyImport_AddModule("__main__")
        )));

        // pass the reference to a_cxx_foo into python:
        bp::object setup_func = main.attr("setup");
        setup_func(a_cxx_foo);

        // now run the python  main  function
        bp::object run_func = main.attr("run");
        run_func();
    }
    catch (bp::error_already_set) {
        PyErr_Print();
    }

    Py_Finalize();

    return 0;
}
问题回答

这里指的是你如何利用pybind11做到这一点:

#include <iostream>
#include <pybind11/pybind11.h>
namespace py = pybind11;

// Define C++ class "Foo"
class Foo {
    std::string s_;
public:
    Foo(const std::string &s) : s_(s) {}
    void doSomething() { std::cout << s_ << std::endl; }
};
typedef std::shared_ptr<Foo> FooPtr;

// Define Python module "bar" and Python class "bar.Foo" wrapping the C++ class
PYBIND11_MODULE(bar, m) {
    py::class_<Foo, FooPtr>(m, "Foo")
        .def("doSomething", &Foo::doSomething);
}

int main(int argc, char **argv)
{
    // Create a C++ instance of Foo
    FooPtr foo = std::make_shared<Foo>("Hello, World!");

    // Initialize Python interpreter and import bar module
    PyImport_AppendInittab("bar", PyInit_bar);
    Py_Initialize();
    PyRun_SimpleString("import bar");

    // Make C++ instance accessible in Python as a variable named "foo"
    py::module main = py::module::import("__main__");
    main.attr("foo") = foo;

    // Run some Python code using foo
    PyRun_SimpleString("foo.doSomething()");

    // Finalize the Python interpreter
    Py_Finalize();
    return 0;
}

我知道这是一个老问题,但这里是使用SWIG的解决办法。

foo.h:

#pragma once
#include <string>

struct Foo{
  Foo();
  Foo(std::string const& s);
  void doSomething();
  std::string m_string;
};

foo.cpp:

#include "foo.h"
#include <iostream>

Foo::Foo() {}

Foo::Foo(std::string const& s) : m_string(s) {}

void Foo::doSomething() {
  std::cout << "Foo:" << m_string << std::endl;
}

foo.i:

%module module
%{
  #include "foo.h"
%}

%include "std_string.i"
%include "foo.h"

Generate the usual SWIG wrapper together with a runtime

swig -python -c++ -Wall foo.i
swig -python -c++ -Wall -external-runtime runtime.h

制作包含<代码>结构的SWIG模块 Foo:

g++ -fPIC -Wall -Wextra -shared -o _module.so foo_wrap.cxx foo.cpp -I/usr/include/python2.7 -lpython2.7

如果你想在多个单元之间分享类型信息,可添加一个论点:-DSWIG_TYPE_TABLE=SomeName

现在这里是“C++”的例子。 Foo 传给口译员

#include "foo.h"
#include <Python.h>
#include "runtime.h"

int main(int argc, char **argv) {
  Py_Initialize();

  PyObject* syspath = PySys_GetObject((char*)"path");
  PyObject* pName = PyString_FromString((char*) ".");
  int err = PyList_Insert(syspath, 0, pName);
  Py_DECREF(pName);

  err = PySys_SetObject((char*) "path", syspath);

  PyObject *main, *module, *pInstance, *run, *setup;

  try {
    main = PyImport_ImportModule("__main__");
    err = PyRun_SimpleString(
        "a_foo = None
"
        "
"
        "def setup(a_foo_from_cxx):
"
        "    print  setup called with , a_foo_from_cxx
"
        "    global a_foo
"
        "    a_foo = a_foo_from_cxx
"
        "
"
        "def run():
"
        "    a_foo.doSomething()
"
        "
"
        "print  main module loaded 
");

    // Load Python module
    module = PyImport_ImportModule("module");

    swig_type_info *pTypeInfo = nullptr;
    pTypeInfo = SWIG_TypeQuery("Foo *");

    Foo* pFoo = new Foo("Hello");
    int owned = 1;
    pInstance =
        SWIG_NewPointerObj(reinterpret_cast<void*>(pFoo), pTypeInfo, owned);

    setup = PyObject_GetAttrString(main, "setup");

    PyObject* result = PyObject_CallFunctionObjArgs(setup, pInstance, NULL);
    Py_DECREF(result);

    run = PyObject_GetAttrString(main, "run");

    result = PyObject_CallFunctionObjArgs(run, NULL);
    Py_DECREF(result);
  }
  catch (...) {
    PyErr_Print();
  }

  Py_DECREF(run);
  Py_DECREF(setup);
  Py_DECREF(pInstance);
  Py_DECREF(module);
  Py_DECREF(main);

  Py_Finalize();
  return 0;
}

以上内容可通过:

g++ -Wall -Wextra -I/usr/include/python2.7 main.cpp foo.cpp -o main -lpython2.7




相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签