我可以将Swift与c++混合使用吗?比如Objective-C .mm文件

Can I mix Swift with C++? Like the Objective-C .mm files

本文关键字:比如 Objective-C 文件 mm Swift c++ 混合 我可以      更新时间:2023-10-16

我刚把我的。m文件改成。mm并使用c++。有没有一种方法可以让斯威夫特做到这一点呢?

混乱可能来自于这样的假设,即仅仅将文件扩展名从.m更改为.mm就可以桥接语言,而实际上,它并没有这样做。引起与.cpp摩擦的不是.mm,而是.h标头,它肯定不是C++标头。


相同的项目:是的。

项目相同,你可以快乐地混合 C , c++ , Objective - C , Objective - C + + , 迅速,甚至组装

  1. ...Bridging-Header.h:你将CObjective-C objective - c++ 暴露给Swift使用这个桥
  2. <ProductModuleName>-Swift.h:显示自动你的Swift类标记为@objcObjective-C
  3. .h:这是棘手的部分,因为它们含糊地用于所有口味的C++或不,Objective或不。当.h不像class那样包含单个 c++ 关键字时,可以将其添加到...Bridging-Header.h中,并将其声明的相应.c .cpp功能的任何函数公开。否则,该头文件必须封装在纯的CObjective-C API中。

同一文件:No.

相同的文件中,您不能混合所有5。在同一个源文件:

  1. .swift:你不能混合Swift与任何
  2. .m:您可以将Objective-CC混合使用。(@Vinzzz)
  3. .mm:您可以将Objective-C c++ 混合使用。这个桥是 objective - c++ 。(@Vinzzz)。
  4. .c: pure C
  5. .cpp:可以混用 c++ &<<strong>装配/strong> (@Vality)
  6. .h:无处不在且模棱两可的C c++ Objective-C objective - c++ ,所以答案是取决于

引用

  • 从c++调用程序集(Brett Hale)
  • 从Objective-C (Svitlana)调用Swift
  • 从Swift (SwiftArchitect, self)调用C, c++, Obj-C, obj - c++
  • 要下载完整的iOS 9, Xcode 7项目,请在Swift Recipes中搜索SO-32541268。

不当你从。m切换到。mm时,你实际上是从Objective-C切换到另一种叫做objective - c++的语言(它有许多细微的差异)。所以你并没有真正使用c++;你使用的是接受大部分c++作为输入的objective - c++(就像c++接受大部分但不是全部的C作为输入一样)。当我说它不完全是c++时,请考虑一个包含名为nil的变量(这是合法的c++)的c++文件,然后尝试将其编译为objective - c++。

Swift没有相同的关系。它不是C或c++的超集,也不能直接在.swift文件中使用。

"用Cocoa和Objective-C使用Swift "也告诉我们:

你不能直接将c++代码导入Swift。相反,为c++代码创建一个Objective-C或C包装器。

我写了一个简单的Xcode 6项目,展示了如何混合使用c++, Objective C和Swift代码:

https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console

在Swift中调用一个Objective C和一个c++函数。

关键是创建一个共享头文件Project-Bridging-Header.h,并把Objective C的头文件放在那里。

请下载该项目作为完整的示例。

你也可以跳过Objective-C文件。只需添加一个带有.cpp源文件的C头文件。头文件中只包含C声明,源文件中包含任何c++代码。然后将C头文件包含在**-Bridging-Header.h.

下面的例子返回一个指向c++对象(struct Foo)的指针,这样Swift就可以将其存储在COpaquePointer中,而不是在全局空间中定义struct Foo。

Foo.h文件(Swift看到的-包含在桥接文件中)

#ifndef FOO_H
#define FOO_H
// Strictly C code here.
// 'struct Foo' is opaque (the compiler has no info about it except that 
// it's a struct we store addresses (pointers) to it.
struct Foo* foo_create();
void foo_destroy(struct Foo* foo);
#endif

源文件Foo.cpp内部(Swift看不到):

extern "C"
{
#include "Foo.h"
}
#include <vector>
using namespace std;
// C++ code is fine here. Can add methods, constructors, destructors, C++ data members, etc.
struct Foo
{
   vector<int> data;
};
struct Foo* foo_create()
{
   return new Foo;
}
void foo_destroy(struct Foo* foo)
{
    delete foo;
}

我刚刚用Swift, Objective-C和c++做了一个小的例子项目。这是一个如何在iOS中使用OpenCV拼接的演示。OpenCV API是c++的,所以我们不能直接从Swift与它对话。我使用一个小包装器类,它的实现文件是objective - c++。文件是干净的Objective-C,所以Swift可以直接与它对话。你必须注意不要间接地将任何c++类型的文件导入到Swift与之交互的头文件中。

项目在这里:https://github.com/foundry/OpenCVSwiftStitch

这是我在clang工具自动化c++/swift通信的尝试。你可以在swift中实例化c++类,继承c++类,甚至覆盖swift中的虚方法。
它会解析你想导出到swift的c++类,并自动生成Objective-C/objective - c++桥。

https://github.com/sandym/swiftpp

Swift不直接兼容c++。你可以通过用Objective-C包装你的c++代码,并在Swift中使用Objective-C包装器来解决这个问题。

不,不在一个文件中。

然而,你可以在Swift项目中使用c++而不需要静态库或框架。就像其他人说的,关键是要使一个Objective-C桥接头#包括C兼容的c++头,这些头被标记为C兼容的extern "C" {}技巧。

视频教程:https://www.youtube.com/watch?v=0x6JbiphNS4

其他答案略有不准确。你实际上可以在同一个文件中混合使用Swift和[Objective-]C[++],尽管不是你期望的那样。

使用swiftc c.swiftclang -x objective-c c.swift编译成一个有效的可执行文件

/* /* */
#if 0
// */
import Foundation
print("Hello from Swift!")
/* /* */
#endif
#include <stdio.h>
int main()
{
    puts("Hello from C!");
    return 0;
}
// */

一个技巧(许多技巧)是

您需要一个单独的头用于桥接obj-c++文件…

你不能像通常那样把@interface和@implementation放在同一个.mm文件中。

在你的桥接头文件中有

#import "Linkage.hpp"

Linkage.hpp有用于联动和联动的@接口。Mm具有。Mm

的@实现

<标题>…你实际上没有 #include " yourcp .hpp"在Linkage.hpp。

你只把#include "yourCpp.hpp"放在联动中。在Linkage.hpp文件中,不是

在许多在线示例/教程中,作者只是将@interface和@implementation放在同一个.mm文件中,就像人们经常做的那样。

这将在非常简单的cpp桥接示例中工作,但是,

问题是:

如果您的yourcp .hpp有任何c++特性(比如第一行#include <something>),那么该进程将失败。

但是如果你只是在Linkage 文件中有#include "yourCpp.hpp"(在。mm文件中有它是可以的,显然你需要)-它工作。

不幸的是,这只是整个过程中的一个提示。

如果这对任何人都有帮助,我也有一个简短的教程,从一个简单的Swift命令行实用程序调用一个简单的c++静态库。这是一个非常简单的概念证明代码。

不涉及Objective-C,只有Swift和c++。c++库中的代码由c++包装器调用,该包装器实现带有外部"C"链接的函数。然后在桥接头中引用该函数,并从Swift中调用。

参见http://www.swiftprogrammer.info/swift_call_cpp.html

我在官方资源中提供了SE-0038的链接,描述为维护对Swift编程语言的修改建议和用户可见的增强。

今天的状态是,这是已被接受但尚未安排的功能请求。

这个链接的目的是引导任何人在正确的方向寻找这个特性

Xcode 15包括swift - c++互操作性支持,允许在同一个项目中使用两种语言,而不需要中间桥接层。

导入c++框架

import CxxImageKit

从Swift调用c++方法

func loadImage(_ image: UIImage) {
    // Load an image into the shared C++ class.
    CxxImageEngine.shared.pointee.loadImage(image)
}

查看更多详细信息:https://developer.apple.com/videos/play/wwdc2023/10172/