这是一个最小的例子。
我有以下 SWIG 接口文件(一体化)
pyhello.i
%module pyhello
%{
#include <iostream>
// Inline definition of my C++ class
class MyInt
{
public:
MyInt(int n) : _n(n) {}
static MyInt* create(int n) { return new MyInt(n); }
int get() const { return _n; }
private:
int _n;
};
%}
%typemap(out) MyInt, MyInt&
{
std::cout << "%typemap(out) MyInt, MyInt&" << std::endl;
$result = PyLong_FromLongLong($1.get()); // $1 is an object or a reference
}
%typemap(out) MyInt*
{
std::cout << "%typemap(out) MyInt*" << std::endl;
$result = PyLong_FromLongLong($1->get()); // $1 is a pointer
}
// Export MyInt (only public stuff is needed here)
class MyInt
{
public:
MyInt(int n);
static MyInt* create(int n);
int get() const;
};
我使用这两个命令编译它(在 Ubuntu 22.04、g++ 11.4.0、python 3.10.12 和 SWIG 4.2.0 下):
swig -c++ -python -o pyhello_wrap.cpp pyhello.i
g++ -fpic -shared pyhello_wrap.cpp `python3-config --cflags` -o _pyhello.so
然后我运行以下 python 脚本:
from pyhello import *
i1 = MyInt.create(5)
print(type(i1))
print(i1)
i2 = MyInt(6)
print(type(i2))
print(i2)
print(i2.get()) # This one fails
...产生以下输出:
%typemap(out) MyInt*
<class 'int'>
5
%typemap(out) MyInt*
<class 'pyhello.MyInt'>
<pyhello.MyInt; proxy of 6 >
Traceback (most recent call last):
File "/****/test_pyhello.py", line 10, in <module>
print(i2.get())
File "/****/pyhello.py", line 73, in get
return _pyhello.MyInt_get(self)
TypeError: in method 'MyInt_get', argument 1 of type 'MyInt const *'
我的问题:
谢谢您的帮助!
在 SWIG Python 中,构造函数受到与
get()
方法相同的类型映射的影响。您拦截它返回的值并将其 this
替换为 int
对象。结果是一个类似 int
的物体。这部分完全在意料之中。
您只能将类型映射应用于选定的方法:
%typemap(out) MyInt* MyInt::create
{
std::cout << "%typemap(out) MyInt*" << std::endl;
$result = PyLong_FromLongLong($1->get()); // $1 is a pointer
}
%newobject MyInt::create;
如果没有它,你就会造成内存泄漏。