Я только что изменил свои .m файлы на .mm и использовал С++. Есть ли способ сделать то же самое с Swift?
Можно ли смешивать Swift с С++? Как и файлы Objective - C.mm
Ответ 1
Нет. Когда вы переключаетесь с .m на .mm, вы фактически переключаетесь с Objective-C на другой язык (который имеет много тонких различий) под названием Objective-C ++. Таким образом, вы не используете С++; вы используете Objective-C ++, который принимает большинство С++ в качестве входных данных (таким же образом, что С++ принимает большинство, но не все C в качестве входных данных). Когда я говорю это не совсем С++, рассмотрим файл С++, который включает переменную с именем nil
(которая является законной С++), а затем попытайтесь скомпилировать ее как Objective-C ++.
Swift не имеет одинаковых отношений. Это не надмножество C или С++, и вы не можете напрямую использовать его в файле .swift
.
"Использование Swift с Cocoa и Objective-C" также сообщает нам:
Вы не можете импортировать код С++ непосредственно в Swift. Вместо этого создайте оболочку Objective-C или C для кода С++.
Ответ 2
Путаница может исходить из предположения, что простое изменение расширения файла от .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 ++, поэтому ответ зависит от этого.
Ссылки
- Вызывать сборку с С++ (Бретт Хейл)
- Вызвать Swift из Objective-C (Svitlana)
- Вызывать C, С++, Obj-C, Obj-С++ из Swift (SwiftArchitect, Я)
- Чтобы загрузить полный проект iOS 9, Xcode 7, найдите SO-32541268 в Swift Recipes.
Ответ 3
Я написал простой проект 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.
Пожалуйста, загрузите проект в качестве полного примера.
Ответ 4
Я только что сделал небольшой проект с использованием Swift, Objective-C и С++. Это демонстрация того, как использовать строчку OpenCV в iOS. API OpenCV - это С++, поэтому мы не можем напрямую разговаривать с ним из Swift. Я использую небольшой класс-оболочку, файл реализации Objective-C ++. Файл заголовка чистый Objective-C, поэтому Swift может напрямую об этом поговорить. Вы должны заботиться о том, чтобы не косвенно импортировать любые файлы С++ - ish в заголовки, с которыми Swift взаимодействует.
Проект находится здесь: https://github.com/foundry/OpenCVSwiftStitch
Ответ 5
Вы также можете пропустить файл 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;
}
Ответ 6
Здесь моя попытка инструмента clang для автоматизации С++/быстрой связи. Вы можете инициализировать классы С++ из swift, наследовать из класса С++ и даже переопределять виртуальные методы в swift.
Он проанализирует класс С++, который вы хотите экспортировать, и быстро сгенерируйте мост Objective-C/Objective-С++.
Ответ 7
Swift напрямую не совместим с С++. Вы можете обойти проблему, обернув свой код на С++ с помощью Objective-C и используя оболочку Objective C в Swift.
Ответ 8
У меня также есть демо-программа для быстрого объединения opencv.
Вы можете загрузить его из https://github.com/russj/swift_opencv3_demo.
Подробнее о демо http://flopalm.com/opencv-with-swift/.
Ответ 9
Нет, не в одном файле.
Однако вы можете использовать С++ в Swift Projects без необходимости использования статической библиотеки или фреймворка. Как и другие пользователи, ключевым моментом является создание заголовка моста Objective-C, который # включает C-совместимые заголовки С++, которые помечены как C, совместимые с extern "C" {} трюк.
Видеоурок: https://www.youtube.com/watch?v=0x6JbiphNS4
Ответ 10
Другие ответы немного неточны. Вы можете смешать как 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;
}
// */
Ответ 11
Одна хитрость (из многих) в том, что
Вам нужен отдельный заголовок для файла моста obj- c++...
Вы не можете просто выбросить @interface и @implementation в один и тот же файл .mm, как это обычно делается.
Так что в вашем заголовочном файле моста у вас есть
#import "Linkage.hpp"
Linkage.hpp имеет @interface для Linkage, а Linkage.mm имеет @implementation для .mm
А затем
... вы на самом деле не #include "yourCpp.hpp" в Linkage.hpp.
Вы только помещаете #include "yourCpp.hpp"
в файл Linkage.mm, не в файле Linkage.hpp.
Во многих онлайн-примерах/руководствах автор просто помещает @interface и @implementation в один и тот же файл .mm, как это часто делается.
Это будет работать в очень простых примерах cpp bridging, но,
Проблема в следующем:
если ваш yourCpp.hpp имеет какие-либо функции c++, которые он обязательно будет иметь (например, первую строку #include <something>
), то процесс завершится неудачей.
Но если вы просто не не имеете #include "yourCpp.hpp"
в заголовочном файле Linkage (это хорошо, если он есть в файле .mm, очевидно, вам нужно) - работы.
Опять же, к сожалению, это всего лишь один совет во всем процессе.
Ответ 12
В случае, если это полезно для всех, у меня также есть краткое руководство по вызову простой статической библиотеки С++ из тривиальной утилиты командной строки Swift. Это действительно убедительное доказательство концепции кода.
Нет Objective-C, только Swift и С++. Код в библиотеке С++ вызывается оболочкой С++, которая реализует функцию с внешней связью "C". Затем эта функция ссылается на заголовок моста и вызывается из Swift.
Ответ 13
Я предоставляю ссылку на SE-0038 в официальном ресурсе, описанном как Это поддерживает предложения по изменениям и видимым для пользователя усовершенствованиям языка Swift.
Статус на сегодняшний день заключается в том, что это запрос функции, который был принят, но еще не запланирован.
Эта ссылка предназначена для управления всеми, кто ищет эту функцию в правильном направлении.