Yanıtlar:
Hayır. .M'den .mm'ye geçtiğinizde, aslında Objective-C'den Objective-C ++ adlı farklı bir dile (pek çok ince farklılığı olan) geçersiniz. Yani gerçekten C ++ kullanmıyorsunuz; Çoğu C ++ 'yı girdi olarak kabul eden Objective-C ++' yı kullanıyorsunuz (C ++ 'nın çoğunu kabul ettiği ancak tüm C'yi girdi olarak kabul etmediği gibi). Tam olarak C ++ olmadığını söylediğimde, adında bir değişken içeren bir C ++ dosyası düşününnil
(yasal C ++ olan) ve ardından bunu Objective-C ++ olarak derlemeye çalışın.
Swift'in ilişkisi aynı değil. C veya C ++ 'nın bir üst kümesi değildir ve ikisini de doğrudan bir .swift
dosyada kullanamazsınız .
"Swift'i Kakao ve Objective-C ile Kullanmak" bize şunları da söyler:
C ++ kodunu doğrudan Swift'e aktaramazsınız. Bunun yerine, C ++ kodu için bir Objective-C veya C sarmalayıcı oluşturun.
.mm
dosyalarınıza gidebilir ve (neredeyse) bitmiş olabilirsiniz. Swift ile öyle değil.
nil
gibiint nil
Bu karışıklık, gerçekte bu türden hiçbir şey yapmadığında, yalnızca bir dosya uzantısını 'den' .m
e değiştirmenin .mm
dilleri köprülemek için ihtiyacınız olan tek şey olduğu varsayımından kaynaklanıyor olabilir . Bu değildir .mm
ile sürtünmeyi neden olduğu .cpp
o, .h
pozitif bir olmamalıdır başlık C++
başlığı.
In aynı projede, sen mutlulukla karıştırabilirsiniz C , C ++ , Objective-C , Objective C ++ , Swift ve hatta Meclis .
...Bridging-Header.h
: C , Objective-C ve Objective-C ++ ' ı Swift'e maruz bırakırsınız Bu köprüyü kullanarak<ProductModuleName>-Swift.h
: Ortaya otomatik sizin Swift ile işaretlenmiş sınıfları @objc
için Objective-C.h
: C , ++ ya da değil, Objective ya da değil tüm çeşitleri için belirsiz bir şekilde kullanıldıkları için bu zor kısımdır . Bir zaman .h
tek içermiyor C ++ anahtar gibi class
, bu eklenebilir ...Bridging-Header.h
ve karşılık gelen işlev ne olursa olsun gösterecektir .c
ya .cpp
da beyan işlevleri. Aksi takdirde, bu başlık ya saf bir C ya da Objective-C API ile sarmalanmalıdır .In aynı dosyanın, aynı olarak tüm 5. karştramazsnz kaynak dosyası :
.swift
: Eğer olamaz mix Swift şeyle.m
: Karıştırabilir Objective-C ile C . ( @Vinzzz ).mm
: Objective-C'yi C ++ ile karıştırabilirsiniz . Bu köprü Objective-C ++ ' dır . ( @Vinzzzz) )..c
: saf C.cpp
: C ++ ve Assembly ( @Vality ) karıştırabilirsiniz.h
: her yerde ve belirsiz C , C ++ , Objective-C veya Objective-C ++ , yani cevap buna bağlıdır.Referanslar
C ++, Objective C ve Swift kodunun nasıl karıştırılacağını gösteren basit bir Xcode 6 projesi yazdım:
https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console
Özellikle örnek, Swift'den bir Hedef C ve bir C ++ işlevi çağırıyor.
Anahtar, ortak bir Project-Bridging-Header.h başlığı oluşturmak ve Objective C başlıklarını oraya koymaktır.
Lütfen projeyi eksiksiz bir örnek olarak indirin.
ObjCtoCPlusPlus.h
/ ".mm", yalnızca C ++ koduna bir Ob-C arabirimi sağlamak amacıyla mevcuttur - burada gerekli bir bileşen olan köprüdür. İçermeleri oldukları yerde bırakın ve ObjCtoCPlusPlus.…
erişmeniz gereken her C ++ yöntemi için dosyalara bir yöntem ekleyin . Sen üzerine okumak iyi edersin sourcemaking.com/design_patterns/adapter
Aradaki Objective-C dosyasını da atlayabilirsiniz . .Cpp kaynak dosyasıyla bir C başlık dosyası eklemeniz yeterlidir. Başlık dosyasında yalnızca C bildirimleri bulunur ve kaynak dosyada herhangi bir C ++ kodu bulunur. Ardından, C başlık dosyasını ** - Bridging-Header.h içine ekleyin.
Aşağıdaki örnek, bir C ++ nesnesine (struct Foo) bir işaretçi döndürür, böylece Swift, küresel alanda tanımlanmış yapı Foo yerine bir COpaquePointer'da depolayabilir.
Foo.h dosyası (Swift tarafından görülür - köprüleme dosyasına dahil edilir)
#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 kaynak dosyasının içinde (Swift tarafından görülmez):
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"
yer almak yerine içerdiği yere sardığımı ilk kez görüyorum #ifdef
. Parlak!
Swift, Objective-C ve C ++ kullanarak küçük bir örnek proje yaptım. İOS'ta OpenCV dikişinin nasıl kullanılacağına dair bir demo. OpenCV API C ++ olduğundan, onunla doğrudan Swift üzerinden konuşamayız. Uygulama dosyası Objective-C ++ olan küçük bir sarmalayıcı sınıf kullanıyorum. Başlık Swift doğrudan bu konuşabilirsiniz böylece dosya, Objective-C temiz. Swift'in etkileşime girdiği başlıklara C ++ - ish dosyalarını dolaylı olarak içe aktarmamaya dikkat etmelisiniz.
Proje burada: https://github.com/foundry/OpenCVSwiftStitch
İşte benim C ++ / hızlı iletişimini otomatikleştirmek için bir clang aracı denemem. C ++ sınıflarını swift'ten alabilir, C ++ sınıfından miras alabilir ve hatta swift'te sanal yöntemleri geçersiz kılabilirsiniz.
Hızla dışa aktarmak istediğiniz C ++ sınıfını ayrıştıracak ve Objective-C / Objective-C ++ köprüsünü otomatik olarak oluşturacaktır.
Swift, C ++ ile doğrudan uyumlu değildir. C ++ kodunuzu Objective-C ile sarmalayarak ve Swift'deki Objective C sarmalayıcısını kullanarak bu sorunu çözebilirsiniz.
Ayrıca opencv'yi hızlı bir şekilde birleştirmek için bir demo programım var.
Bunu https://github.com/russj/swift_opencv3_demo adresinden indirebilirsiniz .
Demo hakkında daha fazla bilgi http://flopalm.com/opencv-with-swift/ .
Hayır, tek bir dosyada değil.
Ancak Swift Projelerinde statik bir kitaplığa veya çerçeveye ihtiyaç duymadan C ++ kullanabilirsiniz. Başkalarının da söylediği gibi, anahtar, "C" haricindeki numara ile C uyumlu olarak işaretlenmiş C uyumlu C ++ başlıklarını # içeren bir Objective-C köprüleme başlığı oluşturmaktır .
Eğitim videosu: https://www.youtube.com/watch?v=0x6JbiphNS4
Diğer cevaplar biraz yanlış. Aslında aynı dosyada Swift ve [Objective-] C [++] 'yi karıştırabilirsiniz, ancak tam olarak beklediğiniz şekilde olmasa da.
Bu dosya (c.swift) hem swiftc c.swift
ve hem de ile geçerli bir yürütülebilir dosyaya derlenirclang -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;
}
// */
Bir numara (birçok) şudur:
Normalde birinin yaptığı gibi aynı .mm dosyasına @interface ve @implementation atamazsınız.
Yani köprü başlık dosyanızda
#import "Linkage.hpp"
Linkage.hpp, Bağlantı ve Bağlantı için @ arayüzüne sahiptir. Mm, .mm için @ uygulaması vardır.
Ve sonra
Yalnızca koymak #include "yourCpp.hpp"
, Linkage.mm dosyasında değil Linkage.hpp dosyasında.
Çoğu çevrimiçi örnekte / öğreticide, yazar, @interface ve @implementation öğelerini, genellikle birinin yaptığı gibi aynı .mm dosyasına koyar.
Bu, çok basit cpp köprüleme örneklerinde çalışacaktır, ancak,
Problem şu:
yourCpp.hpp'nizin kesinlikle yapacağı herhangi bir c ++ özelliği varsa (ilk satır gibi #include <something>
), o zaman işlem başarısız olur.
Sadece Ama eğer yok olması #include "yourCpp.hpp"
Bağlantı içinde başlık dosyası ( 's ince belli ki sen gerekir,, mm dosyasında sahip olmak) - çalışıyor.
Yine, bu maalesef tüm süreçte sadece bir ipucu.
Bunun herkes için yararlı olması durumunda, önemsiz bir Swift komut satırı yardımcı programından basit bir C ++ statik kitaplığı çağırma konusunda kısa bir eğitimim de var. Bu, kodun konsept parçasının gerçekten açık bir kanıtıdır.
Hiçbir Objective-C dahil değil, sadece Swift ve C ++. Bir C ++ kitaplığındaki kod, harici "C" bağlantısına sahip bir işlevi uygulayan bir C ++ sarıcı tarafından çağrılır. Bu işleve daha sonra köprüleme başlığında başvurulur ve Swift'den çağrılır.
Resmi kaynakta SE-0038'e bir bağlantı sağlıyorum. Bu bağlantı , Swift Programlama Dili'nde değişiklik ve kullanıcı tarafından görülebilen geliştirmeler için teklifler sunar.
Bugünkü durum, bunun kabul edilmiş ancak henüz planlanmamış özellik isteği olmasıdır.
Bu bağlantı, bu özelliği arayan herkesi doğru yönde yönlendirmeyi amaçlamaktadır.