调用Endpoint.utilAddPendingJob(作业)遇到麻烦

时间:2019-06-28 20:35:20

标签: python swig pjsua2

我正在尝试从Python调用PJSUA2库,它可以正常工作,但是我遇到了一个障碍,试图调用

void utilAddPendingJob(PendingJob *job)

这将导致以下错误

  

TypeError:在方法“ Endpoint_utilAddPendingJob”中,类型为“ pj :: PendingJob *”的参数2

Python代码如下:

import pjsua2 as pj

class MyJob(pj.PendingJob):
    def __init__(self, text):
        self.text = text

    def execute(self, is_pending = False):
        print(text)

<<SNIP>>

job = MyJob("test")
pj.Endpoint.instance().utilAddPendingJob(job)

我看到的唯一区别是此函数在C ++端使用指针而不是引用。但是,浏览SWIG手册并不重要。

编辑: 这是PendingJob SWIG生成的Python类:

class PendingJob(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, PendingJob, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, PendingJob, name)

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr

    def execute(self, is_pending):
        return _pjsua2.PendingJob_execute(self, is_pending)
    __swig_destroy__ = _pjsua2.delete_PendingJob
    __del__ = lambda self: None
PendingJob_swigregister = _pjsua2.PendingJob_swigregister
PendingJob_swigregister(PendingJob)

然后是方法签名,再次由SWIG生成Python代码:

    def utilAddPendingJob(self, job):
        return _pjsua2.Endpoint_utilAddPendingJob(self, job)

1 个答案:

答案 0 :(得分:0)

这里似乎有一个简单的错误,它阻止SWIG意识到所创建的对象实际上是pj.PendingJob的实例-您尚未调用超类的__init__函数。 / p>

像这样添加它:

class MyJob(pj.PendingJob):
    def __init__(self, text):
        self.text = text
        super().__init__() # Python3 niceness, alternatives available for Python2

我想您会重新营业。

(超类构造函数在SWIG中始终很重要,这是创建实现虚拟功能的真实C ++实例的原因。)

但是,在这种情况下,似乎您使用的包装程序尚未设置为允许pj.PendingJob类上的跨语言多态性。如果您签出pjsip,然后运行此命令:

find . -iname '*.i' -execdir cat {} \; | grep 'director'

然后在任何可见的地方都没有引用PendingJob(也没有宏将其隐藏)。

为了便于理解,让我们通过实验进行验证:

%module(directors="1") test

%director Test2;

%inline %{
struct Test1 {
  virtual ~Test1() {}
  virtual void blah() = 0;
};
%}

%inline %{
struct Test2 {
  virtual ~Test2() {}
  virtual void blah() = 0;
};
%}

通过SWIG运行此命令时,我们看到为两个类生成的__init__不同。对于具有%director指令(即Test2)的类,它是可调用的,并且需要进行大量工作来为跨语言多态性做好准备。对于Test1,我们看到的__init__与您在构造函数中报告的相同,即它只是引发异常,因为类型是抽象的。 (作为参考,它仍然不是完全没用,因为您可以从C ++接收该类型的具体实例,只是不能在Python中创建或扩展它们。)