我能把Swift和c++混在一起吗?比如Objective - C .mm文件

时间:2023-01-13 10:59:12

I just changed my .m files to .mm and use C++. Is there a way to do the same with Swift?

我刚刚把我的。m文件改成了。mm并使用c++。斯威夫特也有同样的方法吗?

12 个解决方案

#1


99  

No. When you switch from .m to .mm you are actually switching from Objective-C to a different language (which has many subtle differences) called Objective-C++. So you're not really using C++; you're using Objective-C++ which accepts most C++ as input (in the same way that C++ accepts most but not all C as input). When I say it's not quite C++, consider a C++ file that includes a variable named nil (which is legal C++) and then try to compile that as Objective-C++.

不。当你从。m切换到。mm时,你实际上是在从Objective-C切换到另一种语言(有很多细微的区别),叫做objective - c++。你不是在用c++;您正在使用Objective-C+,它接受大部分c++作为输入(与c++接受大部分但不是全部C作为输入的方式相同)。当我说它不完全是c++时,考虑一个c++文件,其中包含一个名为nil的变量(它是合法的c++),然后尝试将其编译为objective - c++。

Swift doesn't have the same relationship. It is not a superset of C or C++, and you can't directly use either in a .swift file.

斯威夫特没有同样的关系。它不是C或c++的超集,您不能在.swift文件中直接使用它们。

"Using Swift with Cocoa and Objective-C" also tells us:

“使用Swift with Cocoa和Objective-C”也告诉我们:

You cannot import C++ code directly into Swift. Instead, create an Objective-C or C wrapper for C++ code.

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

#2


133  

The confusion may come from the assumption that merely changing a file extension from .m to .mm is all you need to bridge the languages, when, in reality, it does nothing of that sort. It is not the .mm that causes friction with .cpp, it is the .h header which must positively not be a C++ header.

这种混淆可能来自这样一种假设,即仅仅将文件扩展名从.m更改为.mm是连接语言所需的全部内容,而实际上,它不做任何这类事情。与.cpp产生摩擦的不是.mm,而是.h页眉,它肯定不是c++页眉。


Same project: Yes.

In the same project, you can happily mix C, C++, Objective-C, Objective C++, Swift, and even Assembly.

在同一个项目中,您可以愉快地混合使用C、c++、Objective-C、Objective- c++、Swift甚至汇编。

  1. ...Bridging-Header.h: you expose C, Objective-C and Objective-C++ to Swift using this bridge
  2. ……Bridging-Header。h:你用这座桥把C、Objective-C和objective - c++联系起来。
  3. <ProductModuleName>-Swift.h: exposes automatically your Swift classes marked with @objc to Objective-C
  4. < ProductModuleName >迅速。h:自动将标有@objc的Swift类暴露给Objective-C
  5. .h: this is the tricky part, since they are ambiguously used for all flavors of C, ++ or not, Objective or not. When a .h does not contain a single C++ keyword, like class, it can be added to the ...Bridging-Header.h, and will expose whatever function the corresponding .c or .cpp functionalities it declares. Otherwise, that header must be wrapped in either a pure C or Objective-C API.
  6. h:这是比较棘手的部分,因为它们在C、+或not、Objective或not中都有含糊的用法。当.h不包含单个c++关键字时,例如类,它可以添加到…Bridging-Header中。h,并将暴露它声明的相应的.c或.cpp函数的任何函数。否则,该头必须封装在纯C或Objective-C API中。

Same file: No.

In the same file, you can't mix all 5. In the same source file:

在同一个文件中,你不能把5个文件都混在一起。在同一源文件中:

  1. .swift: you can't mix Swift with anything
  2. 斯威夫特:你不能把斯威夫特和任何东西混在一起
  3. .m: you can mix Objective-C with C. (@Vinzzz)
  4. .m:你可以把Objective-C和c混合(@Vinzzz)
  5. .mm: you can mix Objective-C with C++. This bridge is Objective-C++. (@Vinzzz).
  6. 你可以把Objective-C和c++混在一起。这座桥是objective - c + +。(@Vinzzz)。
  7. .c: pure C
  8. C:纯C
  9. .cpp: you can mix C++ & Assembly (@Vality)
  10. .cpp:你可以混合使用c++和Assembly (@Vality)
  11. .h: ubiquitous and ambiguous C, C++, Objective-C or Objective-C++, so the answer is it depends.
  12. .h: C, c++, Objective-C, Objective-C,或者Objective-C+。

References

引用

#3


69  

I wrote a simple Xcode 6 project that show how to mix C++, Objective C and Swift code:

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

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

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

In particular the example call an Objective C and a C++ function from the Swift.

特别是这个例子从Swift调用一个目标C和一个c++函数。

The key is to create a shared header Project-Bridging-Header.h and put the Objective C headers there.

关键是创建一个共享的header项目- bridge - header。把目标C标头放在这里。

Please download the project as a complete example.

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

#4


26  

I have just made a little example project using Swift, Objective-C and C++. It's a demo of how to use OpenCV stitching in iOS. The OpenCV API is C++ so we can't talk to it directly from Swift. I use a small wrapper class who's implementation file is Objective-C++. The Header file is clean Objective-C, so Swift can talk to this directly. You have to take care not to indirectly import any C++-ish files into the the headers that Swift interacts with.

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

The project is here: https://github.com/foundry/OpenCVSwiftStitch

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

#5


20  

You can also skip the Objective-C file in between. Just add a C header file with a .cpp source file. Have only C declarations in the header file and include any C++ code in the source file. Then include the C header file in the **-Bridging-Header.h.

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

The following example returns a pointer to a C++ object (struct Foo) so Swift can store in a COpaquePointer instead of having struct Foo defined in the global space.

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

Foo.h file (seen by Swift - included in the bridging file)

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

Inside source file Foo.cpp (not seen by Swift):

在源文件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;
}

#6


11  

Here's my attempt at a clang tool to automate C++/swift communication. You can instanciate C++ classes from swift, inherit from C++ class and even override virtual methods in swift.
It will parse the C++ class you want to export to swift and generate the Objective-C/Objective-C++ bridge automatically.

下面是我尝试使用clang工具来自动化c++ /swift通信。您可以从swift中立即生成c++类,从c++类继承,甚至在swift中覆盖虚拟方法。它将解析您想要导出的c++类,并自动生成Objective-C/ objective - c++桥。

https://github.com/sandym/swiftpp

https://github.com/sandym/swiftpp

#7


5  

Swift is not directly compatible with C++. You can work around the issue by wrapping your C++ code with Objective-C, and using the Objective C wrapper in Swift.

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

#8


4  

I also have a demo program for swift combining opencv.

我也有一个swift组合opencv的演示程序。

You can download it from https://github.com/russj/swift_opencv3_demo.

您可以从https://github.com/russj/swift_opencv3_demo下载。

More information about the demo http://flopalm.com/opencv-with-swift/.

有关演示的更多信息,请访问http://lofalm.com/opencv -with-swift/。

#9


4  

No, not in a single file.

不,不是在一个文件里。

However, you may use C++ in Swift Projects without needing a static library or framework. Like others have said, the key is to make an Objective-C bridging header that #includes C-compatible C++ headers that are marked as C compatible with the extern "C" {} trick.

但是,您可以在Swift项目中使用c++,而不需要静态库或框架。就像其他人说的,关键是要做一个Objective-C的桥接头,这个头包含C兼容的c++头,这些头被标记为C,与外部的“C”的技巧兼容。

Video tutorial: https://www.youtube.com/watch?v=0x6JbiphNS4

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

#10


1  

In case this is helpful to anyone, I also have a brief tutorial on calling a simple C++ static library from a trivial Swift command line utility. This is a really bare-bones proof of concept piece of code.

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

No Objective-C involved, just Swift and C++. Code in a C++ library is called by a C++ wrapper that implements a function with extern "C" linkage. That function is then referenced in the bridging header and called from Swift.

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

See http://www.swiftprogrammer.info/swift_call_cpp.html

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

#11


1  

I am providing a link to SE-0038 in the official resource, described as This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.

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

The status as of today is that this is the feature request which has been accepted but not yet scheduled.

目前的状态是,这是已接受但尚未调度的特性请求。

This link is intended to steer anyone looking for this feature in the right direction

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

#12


1  

Other answers are slightly inaccurate. You can actually mix both Swift and [Objective-]C[++] in the same file, though not quite the way you would expect.

其他的答案有点不准确。实际上,您可以在同一个文件中混合使用Swift和[Objective-]C[++],尽管这并不完全符合您的预期。

This file (c.swift) compiles to a valid executable with both swiftc c.swift and clang -x objective-c c.swift

此文件(c.swift)与swiftc c都编译为有效的可执行文件。swift和clang -x objective-c .swift

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

#1


99  

No. When you switch from .m to .mm you are actually switching from Objective-C to a different language (which has many subtle differences) called Objective-C++. So you're not really using C++; you're using Objective-C++ which accepts most C++ as input (in the same way that C++ accepts most but not all C as input). When I say it's not quite C++, consider a C++ file that includes a variable named nil (which is legal C++) and then try to compile that as Objective-C++.

不。当你从。m切换到。mm时,你实际上是在从Objective-C切换到另一种语言(有很多细微的区别),叫做objective - c++。你不是在用c++;您正在使用Objective-C+,它接受大部分c++作为输入(与c++接受大部分但不是全部C作为输入的方式相同)。当我说它不完全是c++时,考虑一个c++文件,其中包含一个名为nil的变量(它是合法的c++),然后尝试将其编译为objective - c++。

Swift doesn't have the same relationship. It is not a superset of C or C++, and you can't directly use either in a .swift file.

斯威夫特没有同样的关系。它不是C或c++的超集,您不能在.swift文件中直接使用它们。

"Using Swift with Cocoa and Objective-C" also tells us:

“使用Swift with Cocoa和Objective-C”也告诉我们:

You cannot import C++ code directly into Swift. Instead, create an Objective-C or C wrapper for C++ code.

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

#2


133  

The confusion may come from the assumption that merely changing a file extension from .m to .mm is all you need to bridge the languages, when, in reality, it does nothing of that sort. It is not the .mm that causes friction with .cpp, it is the .h header which must positively not be a C++ header.

这种混淆可能来自这样一种假设,即仅仅将文件扩展名从.m更改为.mm是连接语言所需的全部内容,而实际上,它不做任何这类事情。与.cpp产生摩擦的不是.mm,而是.h页眉,它肯定不是c++页眉。


Same project: Yes.

In the same project, you can happily mix C, C++, Objective-C, Objective C++, Swift, and even Assembly.

在同一个项目中,您可以愉快地混合使用C、c++、Objective-C、Objective- c++、Swift甚至汇编。

  1. ...Bridging-Header.h: you expose C, Objective-C and Objective-C++ to Swift using this bridge
  2. ……Bridging-Header。h:你用这座桥把C、Objective-C和objective - c++联系起来。
  3. <ProductModuleName>-Swift.h: exposes automatically your Swift classes marked with @objc to Objective-C
  4. < ProductModuleName >迅速。h:自动将标有@objc的Swift类暴露给Objective-C
  5. .h: this is the tricky part, since they are ambiguously used for all flavors of C, ++ or not, Objective or not. When a .h does not contain a single C++ keyword, like class, it can be added to the ...Bridging-Header.h, and will expose whatever function the corresponding .c or .cpp functionalities it declares. Otherwise, that header must be wrapped in either a pure C or Objective-C API.
  6. h:这是比较棘手的部分,因为它们在C、+或not、Objective或not中都有含糊的用法。当.h不包含单个c++关键字时,例如类,它可以添加到…Bridging-Header中。h,并将暴露它声明的相应的.c或.cpp函数的任何函数。否则,该头必须封装在纯C或Objective-C API中。

Same file: No.

In the same file, you can't mix all 5. In the same source file:

在同一个文件中,你不能把5个文件都混在一起。在同一源文件中:

  1. .swift: you can't mix Swift with anything
  2. 斯威夫特:你不能把斯威夫特和任何东西混在一起
  3. .m: you can mix Objective-C with C. (@Vinzzz)
  4. .m:你可以把Objective-C和c混合(@Vinzzz)
  5. .mm: you can mix Objective-C with C++. This bridge is Objective-C++. (@Vinzzz).
  6. 你可以把Objective-C和c++混在一起。这座桥是objective - c + +。(@Vinzzz)。
  7. .c: pure C
  8. C:纯C
  9. .cpp: you can mix C++ & Assembly (@Vality)
  10. .cpp:你可以混合使用c++和Assembly (@Vality)
  11. .h: ubiquitous and ambiguous C, C++, Objective-C or Objective-C++, so the answer is it depends.
  12. .h: C, c++, Objective-C, Objective-C,或者Objective-C+。

References

引用

#3


69  

I wrote a simple Xcode 6 project that show how to mix C++, Objective C and Swift code:

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

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

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

In particular the example call an Objective C and a C++ function from the Swift.

特别是这个例子从Swift调用一个目标C和一个c++函数。

The key is to create a shared header Project-Bridging-Header.h and put the Objective C headers there.

关键是创建一个共享的header项目- bridge - header。把目标C标头放在这里。

Please download the project as a complete example.

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

#4


26  

I have just made a little example project using Swift, Objective-C and C++. It's a demo of how to use OpenCV stitching in iOS. The OpenCV API is C++ so we can't talk to it directly from Swift. I use a small wrapper class who's implementation file is Objective-C++. The Header file is clean Objective-C, so Swift can talk to this directly. You have to take care not to indirectly import any C++-ish files into the the headers that Swift interacts with.

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

The project is here: https://github.com/foundry/OpenCVSwiftStitch

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

#5


20  

You can also skip the Objective-C file in between. Just add a C header file with a .cpp source file. Have only C declarations in the header file and include any C++ code in the source file. Then include the C header file in the **-Bridging-Header.h.

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

The following example returns a pointer to a C++ object (struct Foo) so Swift can store in a COpaquePointer instead of having struct Foo defined in the global space.

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

Foo.h file (seen by Swift - included in the bridging file)

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

Inside source file Foo.cpp (not seen by Swift):

在源文件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;
}

#6


11  

Here's my attempt at a clang tool to automate C++/swift communication. You can instanciate C++ classes from swift, inherit from C++ class and even override virtual methods in swift.
It will parse the C++ class you want to export to swift and generate the Objective-C/Objective-C++ bridge automatically.

下面是我尝试使用clang工具来自动化c++ /swift通信。您可以从swift中立即生成c++类,从c++类继承,甚至在swift中覆盖虚拟方法。它将解析您想要导出的c++类,并自动生成Objective-C/ objective - c++桥。

https://github.com/sandym/swiftpp

https://github.com/sandym/swiftpp

#7


5  

Swift is not directly compatible with C++. You can work around the issue by wrapping your C++ code with Objective-C, and using the Objective C wrapper in Swift.

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

#8


4  

I also have a demo program for swift combining opencv.

我也有一个swift组合opencv的演示程序。

You can download it from https://github.com/russj/swift_opencv3_demo.

您可以从https://github.com/russj/swift_opencv3_demo下载。

More information about the demo http://flopalm.com/opencv-with-swift/.

有关演示的更多信息,请访问http://lofalm.com/opencv -with-swift/。

#9


4  

No, not in a single file.

不,不是在一个文件里。

However, you may use C++ in Swift Projects without needing a static library or framework. Like others have said, the key is to make an Objective-C bridging header that #includes C-compatible C++ headers that are marked as C compatible with the extern "C" {} trick.

但是,您可以在Swift项目中使用c++,而不需要静态库或框架。就像其他人说的,关键是要做一个Objective-C的桥接头,这个头包含C兼容的c++头,这些头被标记为C,与外部的“C”的技巧兼容。

Video tutorial: https://www.youtube.com/watch?v=0x6JbiphNS4

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

#10


1  

In case this is helpful to anyone, I also have a brief tutorial on calling a simple C++ static library from a trivial Swift command line utility. This is a really bare-bones proof of concept piece of code.

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

No Objective-C involved, just Swift and C++. Code in a C++ library is called by a C++ wrapper that implements a function with extern "C" linkage. That function is then referenced in the bridging header and called from Swift.

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

See http://www.swiftprogrammer.info/swift_call_cpp.html

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

#11


1  

I am providing a link to SE-0038 in the official resource, described as This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.

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

The status as of today is that this is the feature request which has been accepted but not yet scheduled.

目前的状态是,这是已接受但尚未调度的特性请求。

This link is intended to steer anyone looking for this feature in the right direction

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

#12


1  

Other answers are slightly inaccurate. You can actually mix both Swift and [Objective-]C[++] in the same file, though not quite the way you would expect.

其他的答案有点不准确。实际上,您可以在同一个文件中混合使用Swift和[Objective-]C[++],尽管这并不完全符合您的预期。

This file (c.swift) compiles to a valid executable with both swiftc c.swift and clang -x objective-c c.swift

此文件(c.swift)与swiftc c都编译为有效的可执行文件。swift和clang -x objective-c .swift

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