用Swift版本5.3调用C函数:使用pthread

5

EDIT3: 从RDerik的代码中重新创建错误。

我最初使用了我从RDerik修改的代码。现在,其他人可能会重新创建错误,我正在运行从这里克隆的未经修改的RDerik代码。

当我运行RDerik的代码时,我会得到以下错误(与下面的EDIT中指出的相同错误):

错误:可选类型“pthread_t?”(即“Optional”)的值必须解包为类型“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的fix。我需要调用的C函数具有以下签名:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg)

以下是我尝试使用Swift调用pthread_create()的代码,第5行是关键:参数&myThread。请参考以下修改自这里的代码:
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参数抛出以下错误: 致命错误:在第5行隐式解包可选值时意外地发现了nil

编辑:

我尝试过的其他事情:

如果我像这样使用而不是来处理pthread:

    var myThread: pthread_t? = nil

我遇到了编译错误:
``` 错误: 可选类型的值 'pthread_t?' (即 'Optional') 必须被解包为类型为 'pthread_t' (即 'UInt') 的值。 ```
提示:使用 '!' 强制解包,如果可选值包含 'nil' 则中止执行。 编辑2: 我还尝试过:
    let result = pthread_create(&myThread, 0, __threadedFunction, pThreadParameter)

错误:无法将类型为“Int”的值转换为预期的参数类型“UnsafePointer<pthread_attr_t>?”


2
出于好奇,您为什么需要特别调用 pthread_create,而不使用Swift可用的其他并发范例(例如Dispatch)之一? - Itai Ferber
2
附加建议:在这种情况下,我经常发现创建一个小的“测试用例”非常有帮助。虽然需要额外的一点工作...但可以节省很多时间来获得所需的解决方案。请尝试以下步骤:1)下载此项目:https://github.com/rderik/rdknitting 2)按照相应的教程进行操作:https://rderik.com/blog/multithreading-with-pthreads-in-swift/。3)一旦您让测试用例正常运行,请将解决方案应用到您的实际项目中。4)如果您在环境中遇到RDerick代码的问题,请发布新的SO问题。 - paulsm4
2
根据您发布的代码,我无法复制此问题,但我必须猜测您的代码与链接代码有很大差异(例如,您在各种位置放置了下划线,而原始代码中没有,在ThreadParameter方面也不同)。你能否发布一个完整的示例以重现此问题? - Rob Napier
1
当我运行RDerik的代码时,我会得到以下错误。您发布的错误是编译器错误,而不是运行时错误。这是您的意思吗?(我下载了它并在Xcode 12.5中编译时没有错误。)我确实在第22行崩溃(分配pThreadParameter.pointee),但我认为这是因为内存管理看起来有问题(没有保留threadParameter)。 - Rob Napier
1
你使用的Xcode版本是什么?我无法获得编译器错误。我可以获得运行时崩溃。我刚刚克隆了它。运行“xed。”选择“我的Mac”和Cmd-R。还尝试在克隆目录中运行“swift run”,它可以编译成功。(然后崩溃了) - Rob Napier
显示剩余14条评论
1个回答

0

我不懂Swift。然而,相应于NIL的是C语言中的NULLNULL再次是一个宏,取决于编译器。因此,它可以定义为#define NULL ((char *)0)或者简单地定义为#define NULL 0。那么,如果你传递pthread_create(&myThread, 0, ...而不是nil会发生什么呢?


谢谢@wired。我尝试了你的建议,并在我的原始帖子中发布了结果(见EDIT2)。 - CodeKat
1
正如所说的,我不知道Swift,但是这个链接可能会有所帮助,因为它涉及到a) Swift和pthread b) 不安全指针 https://dev59.com/QoTba4cB1Zd3GeqP5mdu - user15801843
4
Swift中的nil和C语言中的NULL不是完全相同的东西。在Objective-C中,这基本上是正确的,但在Swift中却不是这样。nilOptional<T>.none是相同的。当通过Objective-C桥接到C语言时,它可以被翻译为0,但在Swift中不能仅仅用0来替换它。 - Rob Napier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接