相关疑难解决方法(0)

什么是使用SWIG包装对象从C++调用Python函数的最简洁方法

我有以下代码,它实现了一个带有Python回调函数的简单C++类(ObjWithPyCallback).我们的想法是用"this"作为单个参数调用Python函数.

问题是,由于ObjWithPyCallback是一个SWIG包装对象,我需要SWIG typeinfo才能创建一个Python对象.

这个问题是它在SWIG生成的文件"ObjWithPyCallback_wrap.cxx"中.SWIG可以生成头文件吗?到目前为止,我还未能实现这一目标.

但是,即使使用头文件,SWIG和我的主要实现之间也存在循环依赖关系,这很烦人.如果可能的话,我想找到一种方法来避免它.最终ObjWithPyCallback最终存在于与Python绑定不同的共享库中.

是否有一个干净的方法来解决这个问题?我知道这篇文章,但它只涉及SWIG_NewPointerObj的机制.

在此先感谢您的帮助!

这是代码:

文件:example.py

import cb

def foo(x=None):
    print("Hello from Foo!")
    # I'd like x to be a reference to a ObjWithPyCallback object.
    print(x)

o = cb.ObjWithPyCallback()
o.setCallback(foo)
o.call()
Run Code Online (Sandbox Code Playgroud)

文件:ObjWithPyCallback.h

#include <Python.h>

class ObjWithPyCallback 
{
   public:

      ObjWithPyCallback();
      void setCallback(PyObject *callback);
      void call();

      PyObject *callback_;
};
Run Code Online (Sandbox Code Playgroud)

文件:ObjWithCallback.cpp

#include "ObjWithPyCallback.h"

#include <iostream>

ObjWithPyCallback::ObjWithPyCallback() : callback_(NULL) {}

void ObjWithPyCallback::setCallback(PyObject* callback)
{
   if (!PyCallable_Check(callback))
   {
      std::cerr << "Object is not callable.\n";
   }
   else
   {
      if ( callback_ …
Run Code Online (Sandbox Code Playgroud)

c++ python swig

12
推荐指数
2
解决办法
6374
查看次数

如何使用SWIG包装cthon函数,该函数在python中接收函数指针

这是我想要做的简化示例.假设我在test.h中有以下c ++代码

double f(double x);
double myfun(double (*f)(double x));
Run Code Online (Sandbox Code Playgroud)

现在这些功能的作用并不重要.重要的是myfun接受一个函数指针.

在我的接口文件中包含test.h文件后,我使用SWIG编译了一个python模块"test".现在,在Python中,我运行以下命令:

import test
f = test.f
Run Code Online (Sandbox Code Playgroud)

这创建了一个正常工作的函数f,它需要一个双精度函数.但是,当我尝试在python中将"f"传递给myfun时,会发生以下情况:

myfun(f)
TypeError: in method 'myfun', argument 1 of type 'double (*)(double)'
Run Code Online (Sandbox Code Playgroud)

我该如何解决?我想我的SWIG接口文件中需要一个typemap声明,但我不确定正确的语法是什么或放在哪里.我试过了

%typemap double f(double);
Run Code Online (Sandbox Code Playgroud)

但那没用.有任何想法吗?

c++ python swig

10
推荐指数
1
解决办法
4269
查看次数

来自SWIG PyObject_Call Segfault的Python回调

我有一个wx.py.Shell.shell小部件,它允许用户执行与我的程序交互的python代码.我希望能够将用户在此空间中定义的函数传递给我的C++代码(通过wxswig生成的自定义小部件包装器)并执行它.

在我的C++代码中,我使用std :: function <>类来调用绑定函数(C++或Python)

所以我创建了一个简单的类来用函数调用操作符包装PyObject.但是当我尝试调用PyObject*时,我得到了一个段错误.

class PyMenuCallback
{
    PyObject *Func;
public:
    PyMenuCallback(const PyMenuCallback &op2);
    PyMenuCallback(PyObject *func);
    ~PyMenuCallback ();

    void operator() (int id);
};
/////////////////////////////////////////////////////////
PyMenuCallback::PyMenuCallback(PyObject *func)
    : Func(func)
{
    Py_XINCREF (Func);
    if(!PyCallable_Check(Func))
        cout << "Not a Callable Callback." << endl; //Throw an exception or something
}

PyMenuCallback::PyMenuCallback(const PyMenuCallback &op2)
    : Func (op2.Func)
{
    Py_XINCREF (Func);
    if(!PyCallable_Check(Func))
        cout << "Not a Callable Callback." << endl;
}

PyMenuCallback::~PyMenuCallback()
{
    Py_XDECREF (Func);
}

void PyMenuCallback::operator() (int id)
{
    cout << "Calling Callback" …
Run Code Online (Sandbox Code Playgroud)

c++ python swig wxpython python-c-api

9
推荐指数
1
解决办法
2164
查看次数

如何使用SWIG包装std :: function对象?

我看过很多类似的问题,但还没有找到解决我特定问题的方法.我试图SWIGify一些使用std :: function的C++ 11代码,所以我可以在我的Java应用程序中使用它.

我遇到过像这样的共享指针:

virtual std::shared_ptr<some::ns::TheThing> getTheThing(unsigned short thingID);
Run Code Online (Sandbox Code Playgroud)

并使用shared_ptr指令成功处理它们,如下所示:

%shared_ptr(some::ns::TheThing);
Run Code Online (Sandbox Code Playgroud)

我遇到过这样的共享指针向量:

virtual std::vector<std::shared_ptr<some::ns::TheThing>> getAllTheThings() const = 0;
Run Code Online (Sandbox Code Playgroud)

并使用如下模板成功处理它们:

%template(ThingVector) std::vector<std::shared_ptr<some::ns::TheThing>>;
Run Code Online (Sandbox Code Playgroud)

现在我有一个像这样的方法:

 void registerThingCallback(std::function<void(std::shared_ptr<some::ns::TheThing>) > func);
Run Code Online (Sandbox Code Playgroud)

我无法让SWIG正确包装它.我已经尝试使用%回调,导演,%模板和%内联功能代码,因为我已经看到所有这些事情的例子,但是还没有能够得到任何似乎接近工作的东西.如果有帮助(清理和减少),这里有一个关于函数调用的更多上下文:

thing_callback.h

#include <functional>

namespace some {
  namespace ns {

    /**
     * Hold some callbacks.
     */
    class ThingCallbacks {
    public:

        /**
         * Registers a callback 
         * @param func The callback function
         */
        void registerThingCallback(std::function<void(std::shared_ptr<some::ns::TheThing>) > func);

    };

  }
}
Run Code Online (Sandbox Code Playgroud)

更新

根据Flexo下面的答案,我更接近解决方案.我能够让下面的例子完全像宣传的那样工作.我尝试将它合并到我的实际代码中,但遇到了问题.为了扩展我之前的简化示例,这里是我对TheThing的定义:

test_thing.h

#ifndef THE_THING_H
#define THE_THING_H

#include <string>

namespace some {
  namespace ns …
Run Code Online (Sandbox Code Playgroud)

c++ java swig c++11 std-function

8
推荐指数
1
解决办法
2229
查看次数

使用SWIG处理std :: function

显然,SWIG不理解std::function和破坏Python绑定.例如,这适用于C++:

// Somewhere in the API
typedef std::function<void(const UnitError & error)> UnitErrorHandler;

// Somewhere else in the API
void Unit::setErrorHandler(const UnitErrorHandler & handler) {}

// In the application code
unit->setErrorHandler([](const UnitError & error){
    std::cerr << error << std::endl;
    std::exit(1);
});
Run Code Online (Sandbox Code Playgroud)

但这会破坏代码(除了为了简单起见而有不同的行为,但这不是重点):

unit.setErrorHandler(lambda error: len(error))
Run Code Online (Sandbox Code Playgroud)

情况与def(普通)未绑定功能相同.那么,有没有人知道这方面的解决方法?

c++ swig c++11

5
推荐指数
1
解决办法
1523
查看次数

标签 统计

c++ ×5

swig ×5

python ×3

c++11 ×2

java ×1

python-c-api ×1

std-function ×1

wxpython ×1