从objective-c++调用swift函数

Posted

技术标签:

【中文标题】从objective-c++调用swift函数【英文标题】:Calling swift function from objective-c++ 【发布时间】:2019-06-04 14:27:24 【问题描述】:

我在调用 swift 方法和在 objective-c++ 代码中使用 swift 类时遇到问题。我有以下课程:

@objc class MetalRenderer : NSObject

    // implementation
    ...

然后我有头文件,其中我有前向声明 @class MetalRenderer; 和源 (.mm) 文件中我包含 "Project-Swift.h" 文件并实例化 swift 类并调用方法那个课,没问题。但是,当我尝试使我的类符合MTKViewDelegate 协议代码不再起作用。这就是我在 swift 中所拥有的:

@objc class MetalRenderer : NSObject, MTKViewDelegate

    // implementation
    ...

    func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) 
        //...
    

    func draw(in view: MTKView) 
        //...
    

.mm 中包含相同的头文件和相同的“Project-Swift.h”文件。但是现在.mm 无法编译,

没有名为“MTKViewDelegate”的类型或协议

我是一名 C++ 开发人员,对 Obj-C/Obj-C++/Swift 了解甚少。我了解“-Swift.h”文件中存在问题,该文件不知道MTKViewDelegate 协议。同一个文件包括具有该协议定义的 Metal 和 MetalKit 框架。然而,这些导入被某些模块的预处理器保护所包围。我发现了一些关于人们有类似问题的帖子,建议的解决方案是摆脱一些包括循环引用,这些引用在我的情况下不存在(我猜),或者在 Objective-C 而不是 Objective-C++ 中使用 swift 代码.我将我的代码包装在 Objective-C 类中并且它再次工作,但我不明白为什么我不能直接从 Objective-C++ 调用它,因为代码基本相同并且我对我的不满意提供包装该代码的不必要的间接性。我的问题是,是否可以直接从objective-c++调用swift类方法,为什么它不起作用(可能是因为那些模块,但它们是什么,它们是如何工作的?)?

【问题讨论】:

Objective-C++ 与 C++ 兼容有很多限制。因此,它没有经过 Apple 的良好测试,因为他们并不真正鼓励它。它确实存在包装遗留的库。如果可能的话,我强烈建议只做纯粹的快速。从 swift 调用 C api 比调用 Objective-C++ api 更容易。 在我的情况下恰恰相反。我的大部分代码库在许多平台上共享,因此它是用 C++ 编写的,并且我在 Obj-C/C++ 中实现了低级平台特定的东西。我想学 swift,所以我决定在 Swift 中编写一些特定于平台的东西,并尽可能避免使用 Obj-C,但这似乎仍然不是一个可行的选择,使用 obj-c/c++ 可能会更好只要。很遗憾。 Objective-C++ 不能使用@import。你需要在某处添加#import,可能在.pch @mezo 所以我建议要么导出与 C 兼容的过程 API,要么包装 C++,然后将其导入 swift。但据我所知,从 Swift 到 Objective-C++ 是可能的,但不鼓励。 @Cy-4AH 我尝试使用 #import 导入 MetalKit,但这没有帮助 【参考方案1】:

然而,这些导入被某些模块的预处理器保护所包围。

看起来您已经回答了您的问题:MetalKit 框架不包括在内。

如果导入整个框架有问题,你可以声明MTKViewDelegate协议原型

【讨论】:

也试过了,没用。而且,我不确定Objective-C/C++,但MTKViewDelegate 的前向声明可能还不够,因为我的类是它的子类(或者就obj-c 而言,符合协议)。在 C++ 中,绝对不可能转发声明类,然后定义从该类派生的类。 那你做错了什么。你的类派生自NSObject,而不是MTKViewDelegate。子类化和一致性是两个很大的不同的东西,而不仅仅是术语。【参考方案2】:

.mm 文件的顶部导入MetalKit

#import <MetalKit/MetalKit.h>
#import "Project-Swift.h"

我遇到了完全相同的问题,这为我解决了问题。

【讨论】:

以上是关于从objective-c++调用swift函数的主要内容,如果未能解决你的问题,请参考以下文章

如何从具有隐藏变量名称(参数前的_)或内部+外部(例如 foo(with bar:))的 Objective-C 调用 Swift 函数

Swift 调用 Objective-C 的可变参数函数

从 Swift 测试文件中调用 Objective-C 类

将json调用语法从Objective-C转换为Swift的正确方法是啥?

在 Swift 上委托 Objective-C 协议

如何从 Swift 调用 Objective-C 类的工厂方法?