Câu trả lời:
Không. Khi bạn chuyển từ .m sang .mm, bạn thực sự đang chuyển từ Objective-C sang một ngôn ngữ khác (có nhiều khác biệt tinh tế) được gọi là Objective-C ++. Vì vậy, bạn không thực sự sử dụng C ++; bạn đang sử dụng Objective-C ++, nơi chấp nhận hầu hết C ++ làm đầu vào (giống như cách mà C ++ chấp nhận hầu hết nhưng không phải tất cả C là đầu vào). Khi tôi nói nó không hoàn toàn là C ++, hãy xem xét một tệp C ++ bao gồm một biến có tên nil
(đó là C ++ hợp pháp) và sau đó thử biên dịch nó thành Objective-C ++.
Swift không có cùng mối quan hệ. Nó không phải là siêu dữ liệu của C hoặc C ++ và bạn không thể sử dụng trực tiếp trong một .swift
tệp.
"Sử dụng Swift với Ca cao và Mục tiêu-C" cũng cho chúng ta biết:
Bạn không thể nhập mã C ++ trực tiếp vào Swift. Thay vào đó, hãy tạo một trình bao bọc Objective-C hoặc C cho mã C ++.
.mm
các tệp của mình và hoàn thành (gần như). Không như vậy với Swift.
nil
, nhưint nil
Sự nhầm lẫn có thể xuất phát từ giả định rằng chỉ thay đổi một phần mở rộng tệp từ .m
thành .mm
là tất cả những gì bạn cần để kết nối các ngôn ngữ, trong khi, trong thực tế, nó không làm gì cả. Nó không phải .mm
là nguyên nhân gây ra ma sát .cpp
, đó là .h
tiêu đề phải tích cực không phải là một C++
tiêu đề.
Trong cùng một dự án, bạn có thể vui vẻ trộn C , C ++ , Objective-C , Objective C ++ , Swift và thậm chí là hội .
...Bridging-Header.h
: bạn hiển thị C , Objective-C và Objective-C ++ cho Swift bằng cách sử dụng cây cầu này<ProductModuleName>-Swift.h
: Lộ tự động của bạn Swift lớp được đánh dấu bằng @objc
để Objective-C.h
: đây là phần khó khăn, vì chúng được sử dụng một cách mơ hồ cho tất cả các hương vị của C , ++ hay không, Objective hay không. Khi một .h
không chứa một từ khóa C ++ , như class
, nó có thể được thêm vào ...Bridging-Header.h
và sẽ hiển thị bất kỳ chức năng nào tương ứng .c
hoặc các .cpp
chức năng mà nó tuyên bố. Mặt khác, tiêu đề đó phải được bọc trong API C hoặc Objective-C thuần túy .Trong cùng một tệp, bạn không thể trộn tất cả 5. Trong cùng một tệp nguồn :
.swift
: bạn không thể trộn Swift với bất cứ thứ gì.m
: Bạn có thể trộn Objective-C với C . ( @Vinzzz ).mm
: bạn có thể trộn Objective-C với C ++ . Cây cầu này là Objective-C ++ . ( @Vinzzz )..c
: C nguyên chất.cpp
: bạn có thể kết hợp C ++ và hội ( @Vality ).h
: có mặt khắp nơi và mơ hồ C , C ++ , Objective-C hoặc Objective-C ++ , vì vậy câu trả lời là tùy thuộc.Người giới thiệu
Tôi đã viết một dự án Xcode 6 đơn giản chỉ ra cách trộn mã C ++, Objective C và Swift:
https://github.com/romitagl/spl/tree/master/C-ObjC-Swift/Performance_Console
Cụ thể, ví dụ này gọi hàm Objective C và hàm C ++ từ Swift.
Chìa khóa là tạo một tiêu đề chung Project-Bridging-Header.h và đặt các tiêu đề Objective C ở đó.
Vui lòng tải về dự án như một ví dụ hoàn chỉnh.
ObjCtoCPlusPlus.h
/ `` .mm` tồn tại cho mục đích duy nhất là cung cấp giao diện Ob-C cho mã C ++. Đây là cầu nối, là thành phần cần thiết ở đây. Để lại bao gồm vị trí của chúng và thêm một phương thức trong các ObjCtoCPlusPlus.…
tệp cho mỗi phương thức C ++ mà bạn cần truy cập. Bạn sẽ làm tốt để đọc qua sourcemaking.com/design_potypes/ad CHƯƠNG
Bạn cũng có thể bỏ qua tệp Objective-C ở giữa. Chỉ cần thêm tệp tiêu đề C với tệp nguồn .cpp. Chỉ có khai báo C trong tệp tiêu đề và bao gồm bất kỳ mã C ++ nào trong tệp nguồn. Sau đó, bao gồm tệp tiêu đề C trong ** - Bridging-Header.h.
Ví dụ sau đây trả về một con trỏ tới một đối tượng C ++ (struct Foo) để Swift có thể lưu trữ trong COpaquePulum thay vì có struct Foo được xác định trong không gian toàn cầu.
Tệp Foo.h (được xem bởi Swift - được bao gồm trong tệp bắc cầu)
#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
Tệp nguồn bên trong Foo.cpp (không thấy bởi 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"
bọc tiêu đề ở vị trí được bao gồm thay vì #ifdef
'ed trong chính tệp tiêu đề. Xuất sắc!
Tôi vừa thực hiện một dự án ví dụ nhỏ bằng Swift, Objective-C và C ++. Đây là bản demo về cách sử dụng khâu OpenCV trong iOS. API OpenCV là C ++ vì vậy chúng tôi không thể nói chuyện trực tiếp với nó từ Swift. Tôi sử dụng một lớp bao bọc nhỏ, tệp thực thi là Objective-C ++. Tệp Header sạch Objective-C, vì vậy Swift có thể nói chuyện trực tiếp với điều này. Bạn phải cẩn thận không nhập gián tiếp bất kỳ tệp C ++ - ish nào vào các tiêu đề mà Swift tương tác.
Dự án ở đây: https://github.com/foundry/OpenCVSwiftStitch
Đây là nỗ lực của tôi tại một công cụ clang để tự động hóa giao tiếp C ++ / swift. Bạn có thể kích hoạt các lớp C ++ từ swift, kế thừa từ lớp C ++ và thậm chí ghi đè các phương thức ảo trong swift.
Nó sẽ phân tích lớp C ++ mà bạn muốn xuất để nhanh chóng và tự động tạo cầu Objective-C / Objective-C ++.
Swift không tương thích trực tiếp với C ++. Bạn có thể giải quyết vấn đề bằng cách gói mã C ++ của mình bằng Objective-C và sử dụng trình bao bọc Objective C trong Swift.
Tôi cũng có một chương trình demo cho nhanh chóng kết hợp opencv.
Bạn có thể tải xuống từ https://github.com/russj/swift_opencv3_demo .
Thông tin thêm về bản demo http://flopalm.com/opencv-with-swift/ .
Không, không phải trong một tập tin duy nhất.
Tuy nhiên, bạn có thể sử dụng C ++ trong Dự án Swift mà không cần thư viện tĩnh hoặc khung. Giống như những người khác đã nói, mấu chốt là tạo một tiêu đề bắc cầu Objective-C bao gồm các tiêu đề C ++ tương thích C được đánh dấu là C tương thích với thủ thuật "C" {} bên ngoài .
Video hướng dẫn: https://www.youtube.com/watch?v=0x6JbiphNS4
Các câu trả lời khác hơi không chính xác. Bạn thực sự có thể trộn cả Swift và [Objective-] C [++] trong cùng một tệp, mặc dù không hoàn toàn theo cách bạn mong đợi.
Tệp này (c.swift) biên dịch thành tệp thực thi hợp lệ với cả swiftc c.swift
và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;
}
// */
Một mẹo (của nhiều người) là
Bạn không thể chỉ ném @interface và @im THỰCation trong cùng một tệp .mm như thường làm.
Vì vậy, trong tệp tiêu đề bắc cầu của bạn, bạn có
#import "Linkage.hpp"
Linkage.hpp có @interface cho Liên kết và Liên kết.mm có @im THỰCation cho .mm
Và sau đó
Bạn chỉ đặt #include "yourCpp.hpp"
tệp Linkage.mm, không phải trong tệp Linkage.hpp.
Trong nhiều ví dụ / hướng dẫn trực tuyến, người viết chỉ cần đặt @interface và @im THỰCation trong cùng một tệp .mm, như người ta thường làm.
Điều đó sẽ làm việc trong các ví dụ bắc cầu cpp rất đơn giản, nhưng,
Vấn đề là:
nếu yourCpp.hpp của bạn có bất kỳ tính năng c ++ nào mà nó chắc chắn sẽ (như dòng đầu tiên #include <something>
), thì quá trình sẽ thất bại.
Nhưng nếu bạn không có tệp tiêu đề#include "yourCpp.hpp"
Liên kết (tốt nhất là có tệp đó trong tệp .mm, rõ ràng bạn sẽ cần) - nó hoạt động.
Một lần nữa, điều này không may chỉ là một mẹo trong toàn bộ quá trình.
Trong trường hợp điều này hữu ích với bất kỳ ai, tôi cũng có một hướng dẫn ngắn gọn về cách gọi thư viện tĩnh C ++ đơn giản từ tiện ích dòng lệnh Swift tầm thường. Đây là một bằng chứng thực sự trần trụi của đoạn mã khái niệm.
Không có Objective-C liên quan, chỉ có Swift và C ++. Mã trong thư viện C ++ được gọi bởi trình bao bọc C ++, thực hiện một chức năng với liên kết "C" bên ngoài. Hàm đó sau đó được tham chiếu trong tiêu đề bắc cầu và được gọi từ Swift.
Tôi đang cung cấp một liên kết đến SE-0038 trong tài nguyên chính thức, được mô tả là Điều này duy trì các đề xuất cho các thay đổi và cải tiến hiển thị của người dùng đối với Ngôn ngữ lập trình Swift.
Tình trạng như ngày nay là đây là yêu cầu tính năng đã được chấp nhận nhưng chưa được lên lịch.
Liên kết này nhằm điều khiển bất cứ ai tìm kiếm tính năng này theo đúng hướng