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

Propertyprop_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 接口文件中。

通过设置正确的命名空间,生成了一个代理,一切正常。