1

我正在尝试从 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)
4

1 回答 1

0

看起来这里有一个简单的错误,它阻止了 SWIG 意识到您正在创建的对象实际上是一个实例pj.PendingJob- 您没有调用超类的__init__函数。

像这样添加:

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 中创建或扩展它们)。

于 2019-06-29T22:26:42.237 回答