[英]How do I invoke a method on a C++ class pointer with swig wrappers?
I'm using SWIG to wrap C++ code for use within a Python testing framework. 我正在使用SWIG来包装C ++代码,以便在Python测试框架中使用。 My problem is that I'm getting a pointer to an instance of a class that I need to then invoke methods on.
我的问题是我得到一个指向类的实例的指针,然后我需要调用方法。 Eg, within my swig file example.i:
例如,在我的swig文件example.i中:
iExample* getMyClassInstance();
...
class iExample
{
public:
virtual void somePureVirtualMethod() = 0;
// ...
};
Now, in python, if I had the class, I could just call the method 现在,在python中,如果我有类,我可以调用该方法
myClassInstance.somePureVirtualMethod()
However, I don't actually have an instance of the class, of course. 但是,我当然没有该类的实例。 I have an opaque pointer generated from SWIG.
我有一个从SWIG生成的不透明指针。 How do I use it?
我该如何使用它? Obviously in Python I can't do
显然在Python中我无法做到
myClassInstancePtr = example.getMyClassInstance()
myClassInstancePtr->somePureVirtualMethod()
I tried using cpointer.i or pointer.i in swig to generate pointer functions, but that's no good, because it's trying to create copies of the class. 我尝试在swig中使用cpointer.i或pointer.i来生成指针函数,但这并不好,因为它正在尝试创建类的副本。 This can't even compile with an interface with pure virtual methods, and even if I wasn't using pure virtual methods, I don't want to create a copy of the class, I just want to invoke something on it!
这甚至无法使用纯虚方法的接口进行编译,即使我没有使用纯虚方法,我也不想创建类的副本,我只想在其上调用一些东西!
SWIG can handle this just fine. SWIG可以处理这个问题。 Make sure you define the interface in SWIG and then it won't be opaque.
确保在SWIG中定义界面,然后它不会是不透明的。 Here's a working example:
这是一个有效的例子:
%module x
%inline %{
// Define the interface.
struct iExample
{
virtual int somePureVirtualMethod() = 0;
};
iExample* getMyClassInstance();
%}
// Implementation, not exposed to Python
%{
struct Internal : public iExample
{
int somePureVirtualMethod() { return 5; }
};
iExample* getMyClassInstance() { return new Internal(); }
%}
Demo: 演示:
>>> import x
>>> i = x.getMyClassInstance()
>>> i.somePureVirtualMethod()
5
However, this implementation will leak an Internal Instance. 但是,此实现将泄漏内部实例。 You may want to implement a way to free it automatically.
您可能希望实现一种自动释放它的方法。 One way is to use
%newobject
and define a virtual destructor. 一种方法是使用
%newobject
并定义虚拟析构函数。 Python will delete the object when there are no more references to it. 当没有对象的引用时,Python将删除该对象。
%module x
%newobject getMyClassInstance;
%inline %{
struct iExample
{
virtual ~iExample() {};
virtual int somePureVirtualMethod() = 0;
};
iExample* getMyClassInstance();
%}
// Implementation
%{
#include <iostream>
struct Internal : public iExample
{
int somePureVirtualMethod() { return 5; }
~Internal() { std::cout << "destroyed" << std::endl; }
};
iExample* getMyClassInstance() { return new Internal(); }
%}
Demo: 演示:
>>> import x
>>> i = x.getMyClassInstance()
>>> i.somePureVirtualMethod()
5
>>> i=2 # reassign i
destroyed # garbage-collected
The simplest answer I've found is to edit your example.i to add in some helper functions to do dereferencing. 我发现最简单的答案是编辑你的example.i以添加一些辅助函数来进行解除引用。 In your swig file example.i:
在您的swig文件example.i中:
{%
...
// Helper function to dereference pointers within python
template <typename T>
T& dereference(T* ptr)
{
return *ptr;
}
...
%}
...
// Make every version of the templated functions we'll need
template <typename T> T& dereference(T* ptr);
%template(dereferencePtr_iExample) dereference<iExample>;
Now in python 现在在python中
myClassInstance = example.dereferencePtr_iExample(example.getMyClassInstance())
myClassInstance.somePureVirtualMethod()
I imagine this method should work generically for other languages like perl as well, and you don't have to screw around with SWIG typemaps. 我想这种方法一般也适用于perl等其他语言,而且你不必使用SWIG类型图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.