SWIG C++ Python:通过引用或指针包装int

Rob*_*obW 9 c++ python swig integer reference

我正在尝试将一些C++函数包装到Python包装器中.为此,似乎SWIG是一种简单易行的方式.

包装工作,但通过引用或指针传递整数时出现问题.由于Python无法使用引用,因此SWIG在内部将这些转换为指针.

一些简单的示例代码:

Blaat.hpp:

#ifndef __BLAAT_HPP__
#define __BLAAT_HPP
class Blaat
{
public:
 int mA;
 float mB;

public:
 Blaat() {}
 void getA(int & fA);
 void setA(const int fA);
 ~Blaat() {}
};

#endif // __BLAAT_HPP__
Run Code Online (Sandbox Code Playgroud)

Blaat.cpp

#include "Blaat.hpp"
#include <iostream>

void Blaat::getA(int & fA) {
 std::cout << "[Blaat::getA] fA = " << fA << std::endl;
 fA = mA;
} 

void Blaat::setA(const int fA) {
 std::cout << "[Blaat::setA] fA = " << fA << std::endl;
 mA = fA;
}
Run Code Online (Sandbox Code Playgroud)

Blaat.i:

%module Blaat
%{
/* Includes the header in the wrapper code */
#include "Blaat.hpp"
%}

/* Parse the header file to generate wrappers */
%include "Blaat.hpp"
Run Code Online (Sandbox Code Playgroud)

将代码转换为Python包装器:

#!/bin/sh
swig -python -c++ -v $1.i 
gcc -c $1_wrap.cxx -fPIC -I/usr/include/python2.6
gcc -shared $1_wrap.o -o _$1<library_path> so -L. -l$1
Run Code Online (Sandbox Code Playgroud)

一切正常.现在,我启动Python并执行:

from Blaat import *
a = Blaat()
b = int(1)
a.setA(b) <-- fine, calls setA() function fine
a.getA(b) <-- does not work
Run Code Online (Sandbox Code Playgroud)

在"getA()"调用时,会发生以下错误:

Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "Blaat.py", line 86, in getA
   def getA(self, *args): return _Blaat.Blaat_getA(self, *args)
TypeError: in method 'Blaat_getA', argument 2 of type 'int &'
Run Code Online (Sandbox Code Playgroud)

请注意,通过引用和指针传递参数时,我都会遇到此问题.查看生成的"Blaat_wrap.cxx"文件,它会在实际类型转换时停止:

res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_int,  0 );
if (!SWIG_IsOK(res2)) {
 SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Blaat_getA" "', argument " "2"" of type '" "int &""'"); 
}
Run Code Online (Sandbox Code Playgroud)

这意味着函数SWIG_ConvertPtr()失败,这很奇怪,因为它检查的类型似乎是SWIGTYPE_p_int.从"setA()"函数中,我们看到类型转换有效(如果通过值传递).

SWIG文档告诉我):

支持C++引用,但SWIG将它们转换回指针.例如,这样的声明:

class Foo {public:double bar(double&a); }

有一个低级别的访问者

double Foo_bar(Foo*obj,double*a){obj-> bar(*a); }

有人可以投入我失踪的东西吗?我在这一点上非常困难...... 发现这篇文章,但这也没有帮助

Chr*_*ard 7

我不认为python有引用返回的概念,但这是我的解决方案:

Blaat.i:

%module Blaat
%include typemaps.i
%apply int &OUTPUT { int & fA };
%{
/* Includes the header in the wrapper code */
#include "Blaat.hpp"
%}

/* Parse the header file to generate wrappers */
class Blaat
{
public:
 Blaat();
 void getA(int & fA);
 void setA(const int fA);
 ~Blaat();
};
Run Code Online (Sandbox Code Playgroud)

b.py:

from Blaat import *
a = Blaat()
b = int(1)
a.setA(b)
b = a.getA()
Run Code Online (Sandbox Code Playgroud)

运行:

python b.py
[Blaat::setA] fA = 1
[Blaat::getA] fA = 63
Run Code Online (Sandbox Code Playgroud)