Я только что изменил свои .m файлы на .mm и использовал С++. Есть ли способ сделать то же самое с Swift?
Нет. Когда вы переключаетесь с .m на .mm, вы фактически переключаетесь с Objective-C на другой язык (который имеет много тонких различий) под названием Objective-C ++. Таким образом, вы не используете С++; вы используете Objective-C ++, который принимает большинство С++ в качестве входных данных (таким же образом, что С++ принимает большинство, но не все C в качестве входных данных). Когда я говорю это не совсем С++, рассмотрим файл С++, который включает переменную с именем nil
(которая является законной С++), а затем попытайтесь скомпилировать ее как Objective-C ++.
Swift не имеет одинаковых отношений. Это не надмножество C или С++, и вы не можете напрямую использовать его в файле .swift
.
"Использование Swift с Cocoa и Objective-C" также сообщает нам:
Вы не можете импортировать код С++ непосредственно в Swift. Вместо этого создайте оболочку Objective-C или C для кода С++.
Путаница может исходить из предположения, что простое изменение расширения файла от .m
до .mm
- это все, что вам нужно, чтобы соединить языки, когда на самом деле он ничего не делает. Не .mm
вызывает трение с .cpp
, это заголовок .h
, который должен положительно не быть заголовком C++
.
В том же проекте вы можете с радостью смешать C, С++, Objective-C, Objective С++, Swift и даже Assembly.
...Bridging-Header.h
: выставляете C, Objective-C и Objective-C ++ в Swift используя этот мост<ProductModuleName>-Swift.h
: автоматически выделяет классы Swift с @objc
до Objective-C.h
: это сложная часть, поскольку они неоднозначно используются для всех ароматов C, ++ или нет, Цель или нет. Если .h
не содержит одного ключевого слова С++, например class
, его можно добавить в ...Bridging-Header.h
и выставить любую функцию, соответствующую .c
или .cpp
, которые он объявляет. В противном случае этот заголовок должен быть обернут либо чистым C, либо Objective-C.В том же файле вы не можете смешивать все 5. В том же исходном файле:
.swift
: вы не можете смешивать Swift с чем-либо.m
: вы можете смешивать Objective-C с C. (@Vinzzz).mm
: вы можете смешивать Objective-C с С++. Этот мост Objective-C ++. (@Vinzzz)..c
: pure C.cpp
: вы можете смешивать С++ и Сборка (@Vality).h
: вездесущий и двусмысленный C, С++, Objective-C или Objective-C ++, поэтому ответ зависит от этого.Ссылки
Я написал простой проект Xcode 6, который показывает, как смешивать код С++, Objective C и Swift:
https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console
В частности, пример вызывает функцию Objective C и С++ из Swift.
Ключом является создание общего заголовка Project-Bridging-Header.h и размещение там заголовков Objective C.
Пожалуйста, загрузите проект в качестве полного примера.
Я только что сделал небольшой проект с использованием Swift, Objective-C и С++. Это демонстрация того, как использовать строчку OpenCV в iOS. API OpenCV - это С++, поэтому мы не можем напрямую разговаривать с ним из Swift. Я использую небольшой класс-оболочку, файл реализации Objective-C ++. Файл заголовка чистый Objective-C, поэтому Swift может напрямую об этом поговорить. Вы должны заботиться о том, чтобы не косвенно импортировать любые файлы С++ - ish в заголовки, с которыми Swift взаимодействует.
Проект находится здесь: https://github.com/foundry/OpenCVSwiftStitch
Вы также можете пропустить файл Objective-C. Просто добавьте файл заголовка C с исходным файлом .cpp. Имеют только C-декларации в файле заголовка и включают любой код С++ в исходный файл. Затем включите файл заголовка C в ** - Bridging-Header.h.
Следующий пример возвращает указатель на объект С++ (struct 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 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
он включен, а не #ifdef
'ed в самом файле заголовка. Brilliant!
Здесь моя попытка инструмента clang для автоматизации С++/быстрой связи. Вы можете инициализировать классы С++ из swift, наследовать из класса С++ и даже переопределять виртуальные методы в swift.
Он проанализирует класс С++, который вы хотите экспортировать, и быстро сгенерируйте мост Objective-C/Objective-С++.
Swift напрямую не совместим с С++. Вы можете обойти проблему, обернув свой код на С++ с помощью Objective-C и используя оболочку Objective C в Swift.
Нет, не в одном файле.
Однако вы можете использовать С++ в Swift Projects без необходимости использования статической библиотеки или фреймворка. Как и другие пользователи, ключевым моментом является создание заголовка моста Objective-C, который # включает C-совместимые заголовки С++, которые помечены как C, совместимые с extern "C" {} трюк.
Видеоурок: https://www.youtube.com/watch?v=0x6JbiphNS4
У меня также есть демо-программа для быстрого объединения opencv.
Вы можете загрузить его из https://github.com/russj/swift_opencv3_demo.
Подробнее о демо http://flopalm.com/opencv-with-swift/.
Другие ответы немного неточны. Вы можете смешать как 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;
}
// */
Я предоставляю ссылку на SE-0038 в официальном ресурсе, описанном как Это поддерживает предложения по изменениям и видимым для пользователя усовершенствованиям языка Swift.
Статус на сегодняшний день заключается в том, что это запрос функции, который был принят, но еще не запланирован.
Эта ссылка предназначена для управления всеми, кто ищет эту функцию в правильном направлении.
В случае, если это полезно для всех, у меня также есть краткое руководство по вызову простой статической библиотеки С++ из тривиальной утилиты командной строки Swift. Это действительно убедительное доказательство концепции кода.
Нет Objective-C, только Swift и С++. Код в библиотеке С++ вызывается оболочкой С++, которая реализует функцию с внешней связью "C". Затем эта функция ссылается на заголовок моста и вызывается из Swift.