Respostas:
Não. Quando você muda de .m para .mm, na verdade, você está mudando do Objective-C para um idioma diferente (que possui muitas diferenças sutis) chamado Objective-C ++. Então você não está realmente usando C ++; você está usando o Objective-C ++, que aceita a maior parte do C ++ como entrada (da mesma forma que o C ++ aceita a maioria, mas não todo o C como entrada). Quando digo que não é bem C ++, considere um arquivo C ++ que inclua uma variável chamada nil
(que é C ++ legal) e tente compilar isso como Objective-C ++.
Swift não tem o mesmo relacionamento. Não é um superconjunto de C ou C ++ e você não pode usá-lo diretamente em um .swift
arquivo.
"Usando Swift com cacau e Objective-C" também nos diz:
Você não pode importar o código C ++ diretamente no Swift. Em vez disso, crie um wrapper Objective-C ou C para código C ++.
.mm
seus arquivos e (quase) pronto. Não é assim com Swift.
nil
, comoint nil
A confusão pode vir da suposição de que apenas alterar uma extensão de arquivo de .m
para .mm
é tudo o que você precisa para conectar os idiomas, quando, na realidade, não faz nada desse tipo. Não é o .mm
que causa atrito .cpp
, é o .h
cabeçalho que não deve ser positivamente um C++
cabeçalho.
No mesmo projeto, você pode combinar felizmente C , C ++ , Objective-C , Objective C ++ , Swift e até Assembly .
...Bridging-Header.h
: você expõe C , Objective-C e Objective-C ++ a Swift usando esta ponte<ProductModuleName>-Swift.h
: Expõe automaticamente seus Swift aulas marcados com @objc
a Objective-C.h
: esta é a parte complicada, pois eles são usados de forma ambígua para todos os tipos de C , ++ ou não, objetivo ou não. Quando a .h
não contém uma única palavra-chave C ++ , como class
, ela pode ser adicionada ao ...Bridging-Header.h
e exporá qualquer função que as funcionalidades correspondentes .c
ou .cpp
declaradas. Caso contrário, esse cabeçalho deve ser agrupado em uma API C ou Objective-C pura .No mesmo arquivo, você não pode misturar todos os 5. No mesmo arquivo de origem :
.swift
: você não pode misturar Swift com nada.m
: Você pode misturar Objective-C com C . ( @Vinzzz ).mm
: você pode misturar Objective-C com C ++ . Essa ponte é Objective-C ++ . ( @Vinzzz )..c
: C puro.cpp
: você pode misturar C ++ e montagem ( @Vality ).h
: onipresente e ambíguo C , C ++ , Objective-C ou Objective-C ++ , então a resposta é que depende.Referências
Eu escrevi um projeto simples do Xcode 6 que mostra como misturar códigos C ++, Objective C e Swift:
https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console
Em particular, o exemplo chama uma função Objective C e C ++ do Swift.
A chave é criar um cabeçalho compartilhado Project-Bridging-Header.h e colocar os cabeçalhos do Objective C lá.
Faça o download do projeto como um exemplo completo.
ObjCtoCPlusPlus.h
/ `` .mm` existe com o único objetivo de fornecer uma interface Ob-C para o código C ++ - é a ponte, que é um componente necessário aqui. Deixe as inclusões onde estão e adicione um método nos ObjCtoCPlusPlus.…
arquivos para cada método C ++ ao qual você precisa acessar. Você faria bem em ler em sourcemaking.com/design_patterns/adapter
Você também pode pular o arquivo Objective-C no meio. Basta adicionar um arquivo de cabeçalho C com um arquivo de origem .cpp. Tenha apenas declarações C no arquivo de cabeçalho e inclua qualquer código C ++ no arquivo de origem. Em seguida, inclua o arquivo de cabeçalho C no ** - Bridging-Header.h.
O exemplo a seguir retorna um ponteiro para um objeto C ++ (struct Foo) para que o Swift possa armazenar em um COpaquePointer em vez de ter struct Foo definido no espaço global.
Arquivo Foo.h (visto por Swift - incluído no arquivo de ponte)
#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
Arquivo de origem interno Foo.cpp (não visto pelo 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"
envolver o cabeçalho no local em que está incluído, e não #ifdef
no próprio arquivo de cabeçalho. Brilhante!
Acabei de fazer um pequeno projeto de exemplo usando Swift, Objective-C e C ++. É uma demonstração de como usar a costura OpenCV no iOS. A API do OpenCV é C ++, portanto não podemos falar com ela diretamente do Swift. Eu uso uma classe de wrapper pequena cujo arquivo de implementação é Objective-C ++. O arquivo Cabeçalho está limpo como Objective-C, para que o Swift possa conversar diretamente com isso. Você deve tomar cuidado para não importar indiretamente nenhum arquivo C ++ para os cabeçalhos com os quais o Swift interage.
O projeto está aqui: https://github.com/foundry/OpenCVSwiftStitch
Aqui está minha tentativa de uma ferramenta clang para automatizar a comunicação rápida em C ++ /. Você pode instanciar classes C ++ a partir do swift, herdar da classe C ++ e até substituir métodos virtuais no swift.
Ele analisará a classe C ++ que você deseja exportar rapidamente e gerará a ponte Objective-C / Objective-C ++ automaticamente.
Swift não é diretamente compatível com C ++. Você pode solucionar o problema agrupando seu código C ++ com Objective-C e usando o wrapper Objective C no Swift.
Eu também tenho um programa de demonstração para combinar rapidamente o opencv.
Você pode baixá-lo em https://github.com/russj/swift_opencv3_demo .
Mais informações sobre a demonstração http://flopalm.com/opencv-with-swift/ .
Não, não em um único arquivo.
No entanto, você pode usar o C ++ em projetos Swift sem precisar de uma biblioteca ou estrutura estática. Como outros já disseram, a chave é criar um cabeçalho de ponte Objective-C que # inclua cabeçalhos C ++ compatíveis com C e marcados como C compatíveis com o truque externo "C" {} .
Tutorial em vídeo: https://www.youtube.com/watch?v=0x6JbiphNS4
Outras respostas são um pouco imprecisas. Você pode realmente misturar Swift e [Objective-] C [++] no mesmo arquivo, embora não exatamente da maneira que você esperaria.
Este arquivo (c.swift) é compilado em um executável válido com ambos swiftc c.swift
eclang -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;
}
// */
Um truque (de muitos) é que
Você não pode simplesmente jogar @interface e @implementation no mesmo arquivo .mm, como costuma fazer normalmente.
Então, no seu arquivo de cabeçalho de ponte, você tem
#import "Linkage.hpp"
Linkage.hpp possui a @interface para Linkage e Linkage.mm possui a @implementation para .mm
E depois
Você só coloca #include "yourCpp.hpp"
no arquivo Linkage.mm, não no arquivo Linkage.hpp.
Em muitos exemplos / tutoriais on-line, o escritor simplesmente coloca o @interface e a @implementation no mesmo arquivo .mm, como costuma fazer.
Isso funcionará em exemplos muito simples de ponte de cpp, mas,
O problema é:
se o seu yourCpp.hpp tiver algum recurso de c ++ que certamente (como a primeira linha #include <something>
), o processo falhará.
Mas se você simplesmente não tiver o arquivo de cabeçalho#include "yourCpp.hpp"
no Linkage (é bom tê-lo no arquivo .mm, obviamente você precisará) - ele funciona.
Mais uma vez, infelizmente, essa é apenas uma dica em todo o processo.
Caso isso seja útil a alguém, também tenho um breve tutorial sobre como chamar uma biblioteca estática C ++ simples a partir de um utilitário trivial de linha de comando Swift. Esta é realmente uma prova básica do código.
Nenhum Objective-C envolvido, apenas Swift e C ++. O código em uma biblioteca C ++ é chamado por um wrapper C ++ que implementa uma função com ligação externa "C". Essa função é então referenciada no cabeçalho da ponte e chamada a partir do Swift.
Consulte http://www.swiftprogrammer.info/swift_call_cpp.html
Estou fornecendo um link para o SE-0038 no recurso oficial, descrito como Isso mantém propostas de alterações e aprimoramentos visíveis ao usuário para o Swift Programming Language.
O status de hoje é que essa é a solicitação de recurso que foi aceita, mas ainda não agendada.
Este link tem como objetivo orientar quem procura esse recurso na direção certa