Acabei de alterar meus arquivos .m para .mm e usar C ++. Existe uma maneira de fazer o mesmo com Swift?
fonte
Acabei de alterar meus arquivos .m para .mm e usar C ++. Existe uma maneira de fazer o mesmo com Swift?
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 umC++
cabeçalho.Mesmo projeto: Sim.
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 ++ , comoclass
, 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 .Mesmo arquivo: Não.
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
fonte
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.
fonte
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 nosObjCtoCPlusPlus.…
arquivos para cada método C ++ ao qual você precisa acessar. Você faria bem em ler em sourcemaking.com/design_patterns/adapterVocê 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)
Arquivo de origem interno Foo.cpp (não visto pelo Swift):
fonte
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
fonte
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.
https://github.com/sandym/swiftpp
fonte
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.
fonte
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/ .
fonte
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
fonte
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
fonte
Um truque (de muitos) é que
Você precisa de um cabeçalho separado para o arquivo de ponte obj-c ++ ...
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
Linkage.hpp possui a @interface para Linkage e Linkage.mm possui a @implementation para .mm
E depois
... você realmente não inclui "yourCpp.hpp" no Linkage.hpp.
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.
fonte
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
fonte
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
fonte