Jawaban:
Tidak. Ketika Anda beralih dari .m ke .mm Anda sebenarnya beralih dari Objective-C ke bahasa yang berbeda (yang memiliki banyak perbedaan halus) yang disebut Objective-C ++. Jadi Anda tidak benar-benar menggunakan C ++; Anda menggunakan Objective-C ++ yang menerima sebagian besar C ++ sebagai input (dengan cara yang sama seperti C ++ menerima sebagian besar tetapi tidak semua C sebagai input). Ketika saya mengatakan itu bukan C ++, pertimbangkan file C ++ yang menyertakan variabel bernama nil
(yang legal C ++) dan kemudian coba kompilasi sebagai Objective-C ++.
Swift tidak memiliki hubungan yang sama. Ini bukan superset dari C atau C ++, dan Anda tidak bisa langsung menggunakan salah satu .swift
file.
"Menggunakan Swift dengan Cocoa dan Objective-C" juga memberi tahu kita:
Anda tidak dapat mengimpor kode C ++ langsung ke Swift. Sebagai gantinya, buat pembungkus Objective-C atau C untuk kode C ++.
.mm
file Anda dan (hampir) selesai. Tidak demikian halnya dengan Swift.
nil
, sepertiint nil
Kebingungan mungkin berasal dari asumsi bahwa hanya mengubah ekstensi file dari .m
menjadi .mm
yang Anda butuhkan untuk menjembatani bahasa, ketika, pada kenyataannya, itu tidak melakukan hal semacam itu. Bukan .mm
yang menyebabkan gesekan dengan .cpp
, melainkan .h
tajuk yang pasti tidak menjadi C++
tajuk.
Dalam proyek yang sama , Anda dapat dengan senang hati mencampur C , C ++ , Objective-C , Objective C ++ , Swift , dan bahkan Assembly .
...Bridging-Header.h
: Anda mengekspos C , Objective-C dan Objective-C ++ ke Swift menggunakan jembatan ini<ProductModuleName>-Swift.h
: memperlihatkan secara otomatis kelas Swift Anda yang ditandai dengan @objc
ke Objective-C.h
: ini adalah bagian yang sulit, karena mereka secara ambigu digunakan untuk semua rasa C , ++ atau tidak, Objektif atau tidak. Ketika a .h
tidak mengandung kata kunci C ++ tunggal , seperti class
, itu dapat ditambahkan ke ...Bridging-Header.h
, dan akan memaparkan fungsi apa pun yang sesuai .c
atau .cpp
fungsionalitas yang dinyatakannya. Kalau tidak, header itu harus dibungkus dengan API C atau Objective-C murni .Dalam file yang sama , Anda tidak dapat mencampur semua 5. Dalam file sumber yang sama :
.swift
: Anda tidak dapat mencampur Swift dengan apa pun.m
: Anda dapat mencampur Objective-C dengan C . ( @Vinzzz ).mm
: Anda dapat mencampur Objective-C dengan C ++ . Jembatan ini adalah Objective-C ++ . ( @Vinzzz )..c
: pure C.cpp
: Anda dapat mencampur C ++ & Assembly ( @Vality ).h
: di mana-mana dan ambigu C , C ++ , Objective-C atau Objective-C ++ , jadi jawabannya tergantung.Referensi
Saya menulis proyek Xcode 6 sederhana yang menunjukkan cara menggabungkan C ++, Objective C dan kode Swift:
https://github.com/romitagl/share/tree/master/C-ObjC-Swift/Performance_Console
Khususnya contoh memanggil fungsi Objective C dan C ++ dari Swift.
Kuncinya adalah membuat header bersama Project-Bridging-Header.h dan meletakkan header Objective C di sana.
Silakan unduh proyek sebagai contoh lengkap.
ObjCtoCPlusPlus.h
/ `` .mm` ada untuk tujuan tunggal menyediakan antarmuka Ob-C untuk kode C ++ — itu adalah jembatan, yang merupakan komponen yang diperlukan di sini. Biarkan menyertakan di mana mereka berada, dan tambahkan metode dalam ObjCtoCPlusPlus.…
file untuk setiap metode C ++ yang perlu Anda akses. Anda sebaiknya membaca lebih dari sourcemaking.com/design_patterns/adapter
Anda juga dapat melewatkan file Objective-C di antaranya. Cukup tambahkan file header C dengan file sumber .cpp. Hanya memiliki deklarasi C dalam file header dan sertakan kode C ++ apa pun dalam file sumber. Kemudian sertakan file header C di ** - Bridging-Header.h.
Contoh berikut mengembalikan pointer ke objek C ++ (struct Foo) sehingga Swift dapat menyimpan dalam COpaquePointer alih-alih mendefinisikan struct Foo di ruang global.
File Foo.h (dilihat oleh Swift - termasuk dalam file bridging)
#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
File sumber di dalam Foo.cpp (tidak terlihat oleh 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"
membungkus header di tempat itu dimasukkan daripada #ifdef
'ed dalam file header itu sendiri. Cemerlang!
Saya baru saja membuat proyek contoh kecil menggunakan Swift, Objective-C dan C ++. Ini adalah demo tentang cara menggunakan jahitan OpenCV di iOS. API OpenCV adalah C ++ sehingga kami tidak dapat berbicara langsung dari Swift. Saya menggunakan kelas pembungkus kecil yang file implementasinya adalah Objective-C ++. File Header bersih Objective-C, sehingga Swift dapat berbicara dengan ini secara langsung. Anda harus berhati-hati untuk tidak mengimpor file C ++-ish secara tidak langsung ke header yang berinteraksi dengan Swift.
Proyeknya ada di sini: https://github.com/foundry/OpenCVSwiftStitch
Inilah upaya saya di alat dentang untuk mengotomatisasi komunikasi C ++ / swift. Anda dapat menginstal kelas C ++ dari swift, mewarisi dari kelas C ++ dan bahkan menimpa metode virtual di swift.
Ini akan mem-parsing kelas C ++ yang ingin Anda ekspor ke swift dan menghasilkan jembatan Objective-C / Objective-C ++ secara otomatis.
Swift tidak kompatibel langsung dengan C ++. Anda dapat mengatasi masalah ini dengan membungkus kode C ++ Anda dengan Objective-C, dan menggunakan pembungkus Objective C di Swift.
Saya juga punya program demo untuk menggabungkan OpenCV dengan cepat.
Anda dapat mengunduhnya dari https://github.com/russj/swift_opencv3_demo .
Informasi lebih lanjut tentang demo http://flopalm.com/opencv-with-swift/ .
Tidak, tidak dalam satu file.
Namun, Anda dapat menggunakan C ++ di Swift Projects tanpa memerlukan pustaka atau kerangka kerja statis. Seperti yang dikatakan orang lain, kuncinya adalah membuat header penghubung Objective-C yang # termasuk header C ++ yang kompatibel dengan C yang ditandai sebagai C kompatibel dengan trik "C" {} eksternal .
Video tutorial: https://www.youtube.com/watch?v=0x6JbiphNS4
Jawaban lain sedikit tidak akurat. Anda sebenarnya dapat mencampur Swift dan [Objective-] C [++] dalam file yang sama, meskipun tidak seperti yang Anda harapkan.
File ini (c.swift) mengkompilasi ke executable yang valid dengan keduanya swiftc c.swift
danclang -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;
}
// */
Salah satu trik (dari banyak) adalah itu
Anda tidak bisa begitu saja membuang @interface dan @implementation dalam file .mm yang sama dengan yang biasa dilakukan.
Jadi dalam file header bridging yang Anda miliki
#import "Linkage.hpp"
Linkage.hpp memiliki @interface untuk Linkage dan Linkage.mm memiliki @implementation untuk .mm
Lalu
Anda hanya memasukkan #include "yourCpp.hpp"
file Linkage.mm, bukan di file Linkage.hpp.
Dalam banyak contoh / tutorial online, penulis cukup meletakkan @interface dan @implementation dalam file .mm yang sama, seperti yang sering dilakukan orang.
Itu akan bekerja dalam contoh penghubung cpp yang sangat sederhana, tetapi,
Masalahnya adalah:
jika yourCpp.hpp Anda memiliki fitur c ++ sama sekali yang pasti (seperti, baris pertama #include <something>
), maka prosesnya akan gagal.
Tetapi jika Anda tidak memiliki #include "yourCpp.hpp"
di header file Linkage (tidak apa-apa untuk memilikinya dalam file .mm, jelas Anda harus) - itu berfungsi.
Sekali lagi ini sayangnya hanya satu tip dalam keseluruhan proses.
Dalam hal ini bermanfaat bagi siapa pun, saya juga memiliki tutorial singkat tentang memanggil perpustakaan statis C ++ sederhana dari utilitas baris perintah Swift yang sepele. Ini adalah bukti yang sangat sederhana dari potongan kode konsep.
Tidak ada Objective-C yang terlibat, hanya Swift dan C ++. Kode dalam pustaka C ++ disebut oleh pembungkus C ++ yang mengimplementasikan fungsi dengan tautan "C" eksternal. Fungsi itu kemudian direferensikan di header bridging dan dipanggil dari Swift.
Saya memberikan tautan ke SE-0038 di sumber resmi, dijelaskan sebagai Ini mempertahankan proposal untuk perubahan dan peningkatan yang terlihat oleh pengguna ke Bahasa Pemrograman Swift.
Status pada hari ini adalah bahwa ini adalah permintaan fitur yang telah diterima tetapi belum dijadwalkan.
Tautan ini dimaksudkan untuk mengarahkan siapa pun yang mencari fitur ini ke arah yang benar