SWIG/Python: 无法访问 Python 回调中引用的参数
SWIG/Python: Unable to access referenced parameter in Python callback
在 SWIG 中,我有一个在 Python 中继承的包装 C++ 基础 class。 C++ 端在 Python 派生的 class 上调用回调,效果很好。不幸的是,回调的参数之一作为参考传递。访问此引用会产生:
Fatal unhandled exception: SWIG director method error. Error detected
when calling 'Base.Start'
test.i
%module(directors="1", allprotected="1") test
%feature("director") Base;
class Base
{
public:
virtual bool Start(const Property& config) = 0; // PASSED AS REFERENCE
};
enum PropertyType{PT_REAL, PT_STRING};
class Property
{
public:
PropertyType GetType() const;
int GetSize() const;
};
在Python中,Start
是正确的callback/invoked。不幸的是,调用 GetType()
或 GetSize()
会产生上述错误。调用作为指针传递的参数的函数进行得很好。
import test
class PyClient(test.Base):
def Start(self, config):
config_size = config.GetSize() // YIELDS ERROR
config_type = config.GetType() // YIELDS ERROR
return True
我想我需要将参数 属性 从引用转换为指针,但我不清楚这在 SWIG 中是如何工作的。
更新
调用的回调中的参数似乎与在 Python
端创建时的基础类型不同。
def Start(self, config):
prop_test = test.Property()
type_test = prop_test.GetType() #FINE
type_test2 = config.GetType() # ERROR
当Property
(prop_test
)在Start()
的Python
端被创建时,它的类型是
<mds.Property; proxy of <Swig Object of type 'Property *' at 0x000001CC24DA3D80> >
而传递的 属性 有一个类型
<Swig Object of type 'Base::Property *' at 0x000001CC24CBE1E0>
我想知道这是否是预期的,或者这可能会导致潜在的问题。
痛饮 4.0.2
任何帮助将不胜感激。
本
您没有提供可重现的示例,所以我只是填补了缺失代码的空白并且它起作用了。如果有帮助,这是我的工作示例:
test.i:
%module(directors="1", allprotected="1") test
%feature("director") Base;
%inline %{
enum PropertyType{PT_REAL, PT_STRING};
class Property
{
PropertyType m_prop;
int m_size;
public:
Property(PropertyType prop, int size) : m_prop(prop), m_size(size) {}
PropertyType GetType() const { return m_prop; }
int GetSize() const { return m_size; }
};
class Base
{
public:
virtual bool Start(const Property& config) = 0;
virtual ~Base() {}
};
void demo(Base* obj) {
Property prop(PT_STRING,2);
obj->Start(prop);
}
%}
ex.py:
import test
class PyClient(test.Base):
def Start(self, config):
config_size = config.GetSize()
config_type = config.GetType()
print(f'{config_size=} {config_type=}')
return True
p = PyClient()
test.demo(p)
输出:
config_size=2 config_type=1
啊,我终于想通了,原来 Property
class 在 C++
代码中在不同的命名空间中,但不在 SWIG 接口文件中。
通过设置正确的命名空间,生成了一个代理,一切正常。
在 SWIG 中,我有一个在 Python 中继承的包装 C++ 基础 class。 C++ 端在 Python 派生的 class 上调用回调,效果很好。不幸的是,回调的参数之一作为参考传递。访问此引用会产生:
Fatal unhandled exception: SWIG director method error. Error detected when calling 'Base.Start'
test.i
%module(directors="1", allprotected="1") test
%feature("director") Base;
class Base
{
public:
virtual bool Start(const Property& config) = 0; // PASSED AS REFERENCE
};
enum PropertyType{PT_REAL, PT_STRING};
class Property
{
public:
PropertyType GetType() const;
int GetSize() const;
};
在Python中,Start
是正确的callback/invoked。不幸的是,调用 GetType()
或 GetSize()
会产生上述错误。调用作为指针传递的参数的函数进行得很好。
import test
class PyClient(test.Base):
def Start(self, config):
config_size = config.GetSize() // YIELDS ERROR
config_type = config.GetType() // YIELDS ERROR
return True
我想我需要将参数 属性 从引用转换为指针,但我不清楚这在 SWIG 中是如何工作的。
更新
调用的回调中的参数似乎与在 Python
端创建时的基础类型不同。
def Start(self, config):
prop_test = test.Property()
type_test = prop_test.GetType() #FINE
type_test2 = config.GetType() # ERROR
当Property
(prop_test
)在Start()
的Python
端被创建时,它的类型是
<mds.Property; proxy of <Swig Object of type 'Property *' at 0x000001CC24DA3D80> >
而传递的 属性 有一个类型
<Swig Object of type 'Base::Property *' at 0x000001CC24CBE1E0>
我想知道这是否是预期的,或者这可能会导致潜在的问题。
痛饮 4.0.2
任何帮助将不胜感激。
本
您没有提供可重现的示例,所以我只是填补了缺失代码的空白并且它起作用了。如果有帮助,这是我的工作示例:
test.i:
%module(directors="1", allprotected="1") test
%feature("director") Base;
%inline %{
enum PropertyType{PT_REAL, PT_STRING};
class Property
{
PropertyType m_prop;
int m_size;
public:
Property(PropertyType prop, int size) : m_prop(prop), m_size(size) {}
PropertyType GetType() const { return m_prop; }
int GetSize() const { return m_size; }
};
class Base
{
public:
virtual bool Start(const Property& config) = 0;
virtual ~Base() {}
};
void demo(Base* obj) {
Property prop(PT_STRING,2);
obj->Start(prop);
}
%}
ex.py:
import test
class PyClient(test.Base):
def Start(self, config):
config_size = config.GetSize()
config_type = config.GetType()
print(f'{config_size=} {config_type=}')
return True
p = PyClient()
test.demo(p)
输出:
config_size=2 config_type=1
啊,我终于想通了,原来 Property
class 在 C++
代码中在不同的命名空间中,但不在 SWIG 接口文件中。
通过设置正确的命名空间,生成了一个代理,一切正常。