Answers:
不。当您从.m切换到.mm时,您实际上是在从Objective-C切换到另一种称为Objective-C ++的语言。因此,您并不是真正在使用C ++。您使用的是Objective-C ++,它接受大多数C ++作为输入(与C ++接受大多数但不是全部C作为输入的方式相同)。当我说它不是完全C ++时,请考虑一个C ++文件,其中包含一个名为nil
(合法C ++),然后尝试将其编译为Objective-C ++。
Swift没有相同的关系。它不是C或C ++的超集,并且您不能在.swift
文件中直接使用它。
“将Swift与Cocoa和Objective-C结合使用”还告诉我们:
您不能将C ++代码直接导入Swift。而是为C ++代码创建一个Objective-C或C包装器。
.mm
文件并(几乎)完成。Swift并非如此。
nil
,例如int nil
这种混乱可能来自于假设,即只改变从文件扩展名.m
来.mm
是所有你需要弥合语言的时候,在现实中,它什么也不做那种。这不是.mm
引起摩擦.cpp
,这是.h
必须积极地不是一个报头C++
报头。
在同一项目中,您可以愉快地混合使用C,C ++,Objective-C,Objective C ++,Swift甚至Assembly。
...Bridging-Header.h
:使用此桥向Swift公开C,Objective-C和Objective-C ++<ProductModuleName>-Swift.h
:自动将标记为Objective-C的Swift类公开@objc
.h
:这是棘手的部分,因为它们是不明确地用于所有风味Ç,++与否,目的或没有。当.h
不包含单C ++关键字,如class
,它可以被添加到...Bridging-Header.h
,并且将暴露的任何起作用的对应.c
或 .cpp
它声明功能。否则,该标头必须包装在纯C或Objective-C API中。在同一个文件中,您不能混合所有5个文件。在同一个源文件中:
.swift
:您不能将Swift与任何东西混合使用.m
:您可以将Objective-C与C混合使用。(@Vinzzz).mm
:您可以将Objective-C与C ++混合使用。该桥是Objective-C ++。(@Vinzzz)。.c
:纯C.cpp
:您可以混合使用C ++和汇编语言(@Vality).h
:无处不在的C,C ++,Objective-C或Objective-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头。
请下载该项目作为完整示例。
ObjCtoCPlusPlus.h
/''。mm`的唯一目的是为C ++代码提供Ob-C接口-它是桥梁,在这里是必不可少的组件。将include保留在原处,并在ObjCtoCPlusPlus.…
文件中为您需要访问的每个C ++方法添加一个方法。您最好阅读sourcemaking.com/design_patterns/adapter
您也可以在两者之间跳过Objective-C文件。只需添加带有.cpp源文件的C头文件即可。头文件中仅包含C声明,并且源文件中包含任何C ++代码。然后,将C头文件包含在**-Bridging-Header.h中。
下面的示例返回一个指向C ++对象(结构Foo)的指针,因此Swift可以存储在COpaquePointer中,而不是在全局空间中定义结构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;
}
extern "C"
将标头包装在包含标头的位置,而不是#ifdef
在标头文件本身中编辑。辉煌!
我刚刚使用Swift,Objective-C和C ++制作了一个小示例项目。这是有关如何在iOS中使用OpenCV缝合的演示。OpenCV API是C ++,因此我们无法直接通过Swift与之交谈。我使用一个小型包装器类,该包装器的实现文件是Objective-C ++。该头文件是干净的Objective-C,所以雨燕进行直接通话这一点。您必须注意不要将任何C ++格式的文件间接导入到Swift与之交互的标头中。
这是我尝试使用自动C ++ / swift通信的clang工具的尝试。您可以从swift实例化C ++类,从C ++类继承,甚至可以在swift中重写虚拟方法。
它将解析要导出的C ++类以快速生成自动生成的Objective-C / Objective-C ++桥。
Swift与C ++不直接兼容。您可以通过使用Objective-C包装C ++代码并在Swift中使用Objective C包装器来解决此问题。
我也有一个演示程序,可以快速组合opencv。
您可以从https://github.com/russj/swift_opencv3_demo下载。
有关演示的更多信息,请参见http://flopalm.com/opencv-with-swift/。
不,不在单个文件中。
但是,您可以在Swift项目中使用C ++,而无需静态库或框架。就像其他人所说的那样,关键是要创建一个Objective-C桥接标头,该标头包含#个与C兼容的C ++标头,这些标头被标记为与外部“ C” {}技巧兼容的C ++标头。
其他答案略有错误。实际上,您可以将Swift和[Objective-] C [++]混合在同一个文件中,尽管并不是您期望的那样。
此文件(c.swift)编译为带有swiftc c.swift
和的有效可执行文件clang -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;
}
// */
(很多)诀窍是
您不能像通常那样将@interface和@implementation放在同一.mm文件中。
因此,在桥接头文件中,
#import "Linkage.hpp"
Linkage.hpp具有@interface用于链接,而Linkage.mm具有@implementation用于.mm
然后
您只放入#include "yourCpp.hpp"
Linkage.mm文件,而不放在Linkage.hpp文件中。
在许多在线示例/教程中,作者经常像通常那样将@interface和@implementation放在同一.mm文件中。
这将在非常简单的cpp桥接示例中起作用,但是,
问题是:
如果yourCpp.hpp确实具有任何c ++功能(例如第一行#include <something>
),则该过程将失败。
但如果你只是不具备#include "yourCpp.hpp"
的联动头文件(它的优良有它在.mm文件,很明显你需要) -它的工作原理。
再次不幸的是,这只是整个过程中的一个技巧。
如果这对任何人都有帮助,我还将提供一个简短的教程,介绍如何从琐碎的Swift命令行实用程序调用简单的C ++静态库。这是概念代码的真正准系统证明。
不涉及Objective-C,仅涉及Swift和C ++。C ++包装器调用C ++库中的代码,该包装器实现具有外部“ C”链接的功能。然后,该函数在桥接头文件中引用,并从Swift调用。