gpt4 book ai didi

python - 在 Python 中从 C++ 继承 Base,使用 SWIG 调用抽象方法

转载 作者:行者123 更新时间:2023-11-28 05:32:16 34 4
gpt4 key购买 nike

我在将 C++ (98) 与 python 3 耦合时遇到了一些问题。我有一些 C++ 中的基类,我想在 Python 中对其进行扩展。一些有问题的方法在 C++ 端是纯虚拟的,因此将在 Python 端实现。

目前,我可以从 C++ 调用抽象方法,并且通过 swig,可以在 Python 中调用特化。凉爽的。我在将参数移交给 Python 时遇到问题..

简化我的问题的最小完整示例:

// iBase.h
#pragma once
#include <memory>

typedef enum EMyEnumeration{
EMyEnumeration_Zero,
EMyEnumeration_One,
EMyEnumeration_Two

}TEMyEnumeration;


class FooBase{
protected:
int a;
public:
virtual int getA() = 0 ;
};

class Foo : public FooBase{
public:
Foo() {a = 2;}
int getA(){return a;}
};

class iBase{
public:

virtual void start() =0;
virtual void run(std::shared_ptr<FooBase> p, TEMyEnumeration enumCode) = 0;
};

在痛饮方面:

// myif.i
%module(directors="1") DllWrapper

%{
#include <iostream>
#include "iBase.h"
%}

%include <std_shared_ptr.i>
%shared_ptr(FooBase)
%shared_ptr(Foo)
%feature("director") FooBase;
%feature("director") iBase;
%include "iBase.h"

运行 swig 为:

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

编译 myif_wrap.cxx -> _DllWrapper.pyd

使用以下代码创建一个 *.exe,它将加载 _DllWrapper.pyd 库(确保它在同一目录中!)。另外,将swig生成的DllWrapper.py复制到exe目录下。

//Main_SmartPtr.cpp
#include "stdafx.h"
#include <Python.h>
#include <windows.h>
#include <string>
#include <memory>
#include "iBase.h"
#include "runtime.h"
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
string moduleName = "ExampleSmartPtr";

// load *.pyd (actually a dll file which implements PyInit__<swigWrapperName>)
auto handle =LoadLibrary("_DllWrapper.pyd");

// getting an instance handle..
Py_Initialize();
PyObject *main = PyImport_AddModule("__main__");
PyObject *dict = PyModule_GetDict(main);

PyObject *module = PyImport_Import(PyString_FromString(moduleName.c_str()));
PyModule_AddObject(main, moduleName.c_str(), module);
PyObject *instance = PyRun_String(string(moduleName+string(".")+moduleName+string("()")).c_str(), Py_eval_input, dict, dict);


//calling start() in the Python derived class..
//PyObject *result = PyObject_CallMethod(instance, "start", (char *)"()");

// trying to call run in the Python derived class..

shared_ptr<Foo> foo = make_shared<Foo>();
EMyEnumeration enumCode = EMyEnumeration_Two;


string typeName1 = "std::shared_ptr <FooBase> *";
swig_type_info* info1 = SWIG_TypeQuery(typeName1.c_str());
auto swigData1 = SWIG_NewPointerObj((void*)(&foo), info1, SWIG_POINTER_OWN);

string typeName2 = "TEMyEnumeration *";
swig_type_info* info2 = SWIG_TypeQuery(typeName2.c_str());
auto swigData2 = SWIG_NewPointerObj((void*)(&enumCode), info2, SWIG_POINTER_OWN);

auto result = PyObject_CallMethod(instance, "run", (char *)"(O)(O)", swigData1, swigData2);

return 0;
}

创建一个新的 Python 文件并将其放在 exe 的目录中:

#ExampleSmartPtr.py
import DllWrapper

class ExampleSmartPtr(DllWrapper.iBase):
def __init__(self): # constructor
print("__init__!!")
DllWrapper.iBase.__init__(self)

def start(self):
print("start")
return 0

def run(self, data, enumCode):
print("run")
print("-> data: "+str(data))
print("-> enumCode: "+str(enumCode))

print (data.getA())
return 1

运行exe的输出是:

__init__!!
run
-> data: (<DllWrapper.FooBase; proxy of <Swig Object of type 'std::shared_ptr< FooBase > *' at 0x00000000014F8B70> >,)
-> enumCode: (<Swig Object of type 'TEMyEnumeration *' at 0x00000000014F89F0>,)

如何将 enumCode“取消引用”为简单的 int?如何在 python 类 run() 中调用 print (data.getA())?在目前的形式下,它不打印任何东西..

最佳答案

这不是真正的答案,但我阅读了讨论 Discussion from 2005这是有道理的,这是不可能的。如果您在 Python 端,请执行以下操作,您会将枚举“解除引用”为一个简单的整数。

import ExampleSmartPtr

instance = ExampleSmartPtr.ExampleSmartPtr()
swigData1 = ExampleSmartPtr.DllWrapper.Foo()
swigData2 = ExampleSmartPtr.DllWrapper.EMyEnumeration_Two
instance.run(swigData1,swigData2)

这将打印

__init__!!
run
-> data: <DllWrapper.Foo; proxy of <Swig Object of type 'std::shared_ptr< Foo > *' at 0x7f8825c0b7e0> >
-> enumCode: 2

我认为问题是两个不同的 vtables 在起作用。原始 C++ vtable 和 Swig Object 的 vtable。只是好奇,在什么情况下有兴趣在 C++ 中使用 C++ 类的 Python 后代?

关于python - 在 Python 中从 C++ 继承 Base,使用 SWIG 调用抽象方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39189594/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com