我正在尝试从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)
答案 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中创建或扩展它们。)