将swift线程注册为pj_thread

时间:2015-11-29 22:59:28

标签: ios c multithreading pjsip swift2.1

我目前正在使用pjSIP和swift开发iOS应用程序。

我在.c文件中有一个方法用来打电话,让它成为

void makeCall(const char *destUri){
    ...
    status = pjsua_call_make_call(...
}

我得到了一个从主线程调用的swift方法,它从C文件调用makeCall函数。

如果我这样做,应用程序崩溃并说我需要在调用pjLIP函数之前将线程注册到pjSIP。

要将线程注册到pjSIP,我需要调用函数pj_thread_register

我尝试将该线程添加为UnsafeMutablePointer。

我的电话现在看起来像这样:

void makeCall(const char *destUri, long threadDesc, pj_thread_t **thread){
    ...
    pj_thread_register(NULL, &threadDesc, thread);
    status = pjsua_call_make_call(...
}


internal static func makeSIPCall(numberToCall: String){
    ...
    let destination = ... //my call destination
    let thread : NSThread = NSThread.currentThread()
    let observer = UnsafeMutablePointer<CopaquePointer>(Unmanaged.passUnretained(thread.self).toOpue())

    makeCall(destination, Int(thread.description)! as Clong, observer)

}

主题1:EXC_Breakpoint和致命错误“在解包可选值时发现nil”

那么如何将线程所需的属性从swift传递给C?

2 个答案:

答案 0 :(得分:2)

尽量不要从swift发送引用,但直接在你的内容中使用它 .C-文件:

void makeCall(const char *destUri, long threadDesc, pj_thread_t **thread){
    ...
    pj_thread_desc a_thread_desc;
    pj_thread_t *a_thread;

    if (!pj_thread_is_registered()) {
        pj_thread_register(NULL, a_thread_desc, &a_thread);
    }
    status = pjsua_call_make_call(...
}

来源:ipjsua(构建pjSIP后获得的演示项目)

答案 1 :(得分:0)

似乎可以编写与Swift中接受的答案中提到的功能相同的功能。

func registerThread() {
   if pj_thread_is_registered() == 0 {
     var thread: OpaquePointer?
     var threadDesc = Array(repeating: 0, count: Int(PJ_THREAD_DESC_SIZE))                      
     pj_thread_register(nil, &codecInfos[0], &thread)
   }
}

threadDesc thread 将在 pj_thread_register 返回后填充。

这种行为对我来说并不明显,因为没有有关线程的任何信息都明确传递给 pj_thread_register 。但是我可以从任何GCD派遣队列中调用此函数,并且这将有条件地注册所使用的线程。