从 Swift 5.3 版调用 C 函数:使用 pthreads
Posted
技术标签:
【中文标题】从 Swift 5.3 版调用 C 函数:使用 pthreads【英文标题】:Calling C function from Swift version 5.3: using pthreads 【发布时间】:2021-05-24 21:13:53 【问题描述】:EDIT3:从 RDerik 的代码中重新创建错误
我最初是从我从 RDerik 修改的代码开始的。现在,其他人可能会重新创建错误,我正在运行从 here 克隆的 RDerik 未修改的代码。
当我运行 RDerik 的代码时,我得到以下错误(我在 EDIT 中记录的相同错误:下面):
错误:可选类型“pthread_t?”的值(又名“可选”)必须解包为“pthread_t”(又名“UInt”)类型的值
注意:如果可选值包含
nil
,则使用!
强制解包以中止执行
错误:无法转换类型 '(UnsafeMutableRawPointer) -> UnsafeMutableRawPointer?' 的值到预期的参数类型'@convention(c) (UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer?' let result = pthread_create(&myThread, nil, threadedFunction, pThreadParameter)
我通过将threadedFunction()
的函数头更改为:
func threadedFunction(pointer: UnsafeMutableRawPointer!) -> UnsafeMutableRawPointer?
原帖:
我知道这个问题之前已经回答过,但我无法找到与 Swift 5.3 兼容的修复程序。 我需要调用的 C 函数有这个签名:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg)
下面的第 5 行是我调用pthread_create()
的 Swift 尝试。具体来说,我的问题在于第一个参数:&myThread
。
我的密码:(修改自here)
var myThread: pthread_t! = nil
var threadParameter = _ThreadParameter(threadIdentifier: _ThreadIdentifier(id: ""), pxT: self)
var pThreadParameter = UnsafeMutablePointer<_ThreadParameter>.allocate(capacity:1)
pThreadParameter.pointee = threadParameter
let result = pthread_create(&myThread, nil, __threadedFunction, pThreadParameter)
错误:
调用 pthread_create 时,myThread 参数会引发以下错误: 致命错误:在隐式展开 Optional 值时意外发现 nil,第 5 行
编辑:
我尝试过的其他事情:
如果我对 pthread 使用 ?
而不是 !
,如下所示:
var myThread: pthread_t? = nil
我得到编译错误:
错误:可选类型“pthread_t?”的值(又名“可选”)必须解包为“pthread_t”(又名“UInt”)类型的值
注意:使用 '!' 强制展开如果可选值包含'nil'则中止执行
EDIT2:
也试过了:
let result = pthread_create(&myThread, 0, __threadedFunction, pThreadParameter)
错误:无法将“Int”类型的值转换为预期的参数类型“UnsafePointer
?”
【问题讨论】:
好帖子,有有用的链接:***.com/a/63332736/421195 出于好奇,为什么您需要专门调用pthread_create
,而不是使用 Swift 可用的其他并发范例之一(例如 Dispatch)?
附加建议:在这种情况下,我经常发现创建一个小的“测试用例”非常有帮助。一些额外的前期工作......但可以节省大量时间来获得您需要的解决方案。试试这个:1)下载这个项目:github.com/rderik/rdknitting 2)完成相应的教程:rderik.com/blog/multithreading-with-pthreads-in-swift。 3) 一旦你的测试用例工作起来,将解决方案应用到你的实际项目中。 4) 如果您在环境中遇到 RDerick 代码问题,请发布新的 SO 问题。
ALSO:你试过有线的suggestion:let result = pthread_create(&myThread, 0, __threadedFunction, pThreadParameter)
吗?发生了什么?
鉴于您发布的代码,我无法重现这一点,但我不得不对您的代码与您链接到的代码有何不同做出很多猜测(例如,您已将在不同的地方下划线它们不在原始代码中,并且您的 ThreadParameter 不同)。你能发布一个完整的例子来重现它吗?
【参考方案1】:
我不知道斯威夫特。然而,在 c.NULL
中,对应于 NIL
的 NULL
又是一个宏,具体取决于编译器。所以它既可以定义为#define NULL ((char *)0)
,也可以简单地定义为#define NULL 0
。那么如果你传递 pthread_create(&myThread, 0, ...
而不是 nil 会发生什么?
【讨论】:
谢谢@wired。我尝试了您的建议,并在我的原始帖子中的 EDIT2 下发布了结果。 如前所述,我不知道 swift,但这个链接可能会有所帮助,因为它处理 a) swift & pthreads b) 不安全指针 ***.com/questions/26449990/… Swift 的 nil 与 C 的 NULL 不同。在 ObjC 中,这基本上是正确的,但在 Swift 中则不然。nil
与 Optional<T>.none
相同。当桥接到 C(通过 ObjC)时,它可以被翻译成 0,但你不能在 Swift 中这样替换它。以上是关于从 Swift 5.3 版调用 C 函数:使用 pthreads的主要内容,如果未能解决你的问题,请参考以下文章
从 Swift 调用 Objective C 和 C 传递回调函数
从 Swift 调用带有数组指针和 int 指针的 C 函数