Posso misturar Swift com C++? Como o Objective-C.mm ficheiros
13 answers
nil
(que é C++ legal) e então tente compilar isso como Objective-C++.
O Swift não tem a mesma relação. Não é um superconjunto de C ou C++, e você não pode usar diretamente em um arquivo .swift
.
"usando Swift com cacau e Objective-C" {[9] } também nos diz:
Não pode importar o código C++ directamente para o Swift. Em vez disso, crie um Papel Objetivo-C ou C para o código C++.
A confusão pode vir da suposição de que simplesmente mudar uma extensão de arquivo de {[[0]} para .mm
é tudo o que você precisa para ligar as línguas, quando, na realidade, não faz nada desse tipo. Não é o .mm
que causa fricção com .cpp
, é o cabeçalho .h
que não deve ser um cabeçalho C++
.
O mesmo projecto: Sim.
No mesmo projecto , podem misturar-se alegremente {[[30]}C, C++, Objective-C , Objectivo C++, Swift , e mesmo montagem .
-
...Bridging-Header.h
: você expor C, objective-C e objective-C++ para Swift usando esta ponte -
<ProductModuleName>-Swift.h
: expõeautomaticamente as suas classes Swift marcadas com@objc
a Objectivo-C -
.h
: esta é a parte complicada, uma vez que eles são ambíguos usados para todos os sabores de C, ++ ou não, objectivo ou não. Quando um.h
não contém uma única C++ palavra-chave, comoclass
, pode ser adicionado ao...Bridging-Header.h
, e irá expor qualquer que seja a função correspondente.c
ou.cpp
funcionalidades declara. Caso contrário, esse cabeçalho deve ser embrulhado numa API pura ou objectiva-C .
O mesmo ficheiro: não.
No mesmo ficheiro , Não Podes misturar todos os 5. Na mesma fonte ficheiro:
-
.swift
: Youcan'T mix Swift with anything -
.m
: pode misturar Objective-C com C . ([100]}@Vinzzz) -
.mm
: pode misturar Objective-C com C++. Esta ponte é Objective-C++. (@Vinzzz ). -
.c
: puro -
.cpp
: pode misturar ++ & montagem (@Vality) -
.h
: onipresente e ambíguo C, C++, objective-C ou objective-C++, então a resposta é depende.
Referências
- Invocar a montagem de C++ (Brett Hale)
- Invoque Swift do Objective-C (Svitlana)
- invoque C, C++, Obj-C, Obj-C++ da Swift (SwiftArchitect , self)
- To faça o download de um projecto iOS 9 completo, Xcode 7, procure por SO-32541268 em receitas Swift.
Eu escrevi um projecto Xcode 6 simples que mostra como misturar c++, Objectivo C e Código Swift:
Https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console
Em particular, o exemplo chama uma função C objectiva e uma função C++ a partir do Swift.
A chave é criar um projecto de cabeçalho partilhado-Bridging-Header.h e colocar os cabeçalhos de objectivo C.
Faça o download do projecto como um exemplo completo.
Você também pode saltar o ficheiro Objective-C no meio. Basta adicionar um ficheiro de cabeçalho C com um .ficheiro de código cpp. Ter apenas declarações C no ficheiro header e incluir qualquer código C++ no ficheiro de código. Em seguida, incluir o arquivo C header no * * -Bridging-Header.h.
O seguinte exemplo devolve um ponteiro a um objecto c++ (struct Foo) para que a Swift possa armazenar num COpaquePointer em vez de ter a struct Foo definida no espaço global.
Foo.h file (Visto Pela Swift - included no ficheiro de ligação)
#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
Dentro do ficheiro de código Foo.cpp (not seen by 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;
}
Acabei de fazer um pequeno projecto de exemplo usando Swift, Objective-C E C++. É uma demonstração de como usar stitching OpenCV em iOS. A API OpenCV é C++ por isso não podemos falar com ela diretamente da Swift. Eu uso uma pequena classe de papel que o ficheiro de implementação é Objective-C++. O ficheiro Header é clean Objective-C, por isso o Swift pode falar directamente com isto. Você tem que ter o cuidado de não importar indiretamente nenhum arquivo C++-ish para os cabeçalhos que interage com a Swift.
O projecto está aqui: https://github.com/foundry/OpenCVSwiftStitchIrá processar a Classe C++ que deseja exportar para a swift e gerar automaticamente a Ponte Objective-C/Objective-C++.
O Swift não é directamente compatível com o c++. Você pode trabalhar em torno do problema, embrulhando o seu código C++ com Objective-C, e usando o invólucro Objective C no Swift.
Também tenho um programa de demonstração para a swift combinando opencv.
Você pode baixá-lo de https://github.com/russj/swift_opencv3_demo.
Mais informações sobre a demo http://flopalm.com/opencv-with-swift/.
No entanto, pode usar o C++ em projectos Swift sem necessitar de uma biblioteca estática ou de uma estrutura. Como outros já disseram, a chave é fazer um cabeçalho Objectivo-C que #inclui cabeçalhos c++ compatíveis com C que são marcados como C compatíveis com o extern "C" {}} trick.
Tutorial em Vídeo: https://www.youtube.com/watch?v=0x6JbiphNS4
Outras respostas são ligeiramente inexactas. Você pode realmente misturar tanto Swift e [Objective -] C [++] no mesmo arquivo, embora não exatamente como você esperaria.
Este ficheiro (C. swift) compila para um executável válido com swiftc c.swift
e 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;
}
// */
Precisa de um cabeçalhoseparado para o seu ficheiro obj-c++ em Ponte...
Você não pode simplesmente jogar a interface @e a implementação @no mesmo ficheiro. mm como acontece normalmente.
Então, no seu ficheiro de cabeçalho de ponte, tem
#import "Linkage.hpp"
Ligação.hpp tem a interface @para ligação e Linkage.mm tem a @implementation for. mm
E depois
...não incluas "yourCpp".hpp " in Ligacao.hpp.
Só puseste #include "yourCpp.hpp"
no Linkage.mm file, Não na ligação.ficheiro hpp.
Em muitos exemplos/tutoriais online, o escritor simplesmente coloca a interface @e a implementação @no mesmo ficheiro .mm, como acontece frequentemente.
Isso vai funcionar em exemplos simples de pontes cpp, mas,
O problema é:
Se o seu CPMP.o hpp tem quaisquer funcionalidades em C++ que certamente irá ter (como a primeira linha #include <something>
), então o processo irá falhar.
Mas se você apenas não tem o #include "yourCpp.hpp"
na Ligação cabeçalho arquivo (é bom tê-lo no .mm de arquivo, obviamente, você vai precisar) - ele funciona.
No caso de isto ser útil para alguém, também tenho um breve tutorial sobre a chamada de uma simples biblioteca estática C++ a partir de um utilitário de linha de comandos Swift trivial. Esta é uma prova nua do conceito de código.
Sem Objectivo - C envolvido, apenas Swift e c++. O código em uma biblioteca C++ é chamado por um invólucro C++ que implementa uma função com ligação externa "C". Essa função é então referenciada no cabeçalho bridging e chamada de Swift.
Estou a fornecer uma ligação a SE-0038 no recurso oficial, descrito como Isto mantém propostas de alterações e melhorias visíveis para o utilizador na Linguagem de programação Swift.
O status a partir de hoje é que este é o recurso pedido que foi aceite, mas ainda não agendado.
Esta ligação destina-se a orientar qualquer pessoa que procure esta funcionalidade na direcção certa