Posso misturar Swift com C++? Como o Objective-C.mm ficheiros

Acabei de mudar a minha .M files to. mm and use C++. Há alguma maneira de fazer o mesmo com o Swift?

Author: Cœur, 2014-06-04

13 answers

Não. Quando mudares .m para. mm você está realmente mudando do Objective-C para uma linguagem diferente (que tem muitas diferenças sutis) chamada Objective-C++. Então você não está realmente usando C++; Você está usando Objective-C++ que aceita a maioria de C++ como entrada (da mesma forma que C++ aceita a maioria, mas não todos como entrada). Quando eu disser que não é bem C++, considere um arquivo C++ que inclui uma variável chamada 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++.

 111
Author: Rob Napier, 2015-10-25 18:41:23

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 .

  1. ...Bridging-Header.h: você expor C, objective-C e objective-C++ para Swift usando esta ponte
  2. <ProductModuleName>-Swift.h: expõeautomaticamente as suas classes Swift marcadas com @objc a Objectivo-C
  3. .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, como class, 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:

  1. .swift: Youcan'T mix Swift with anything
  2. .m: pode misturar Objective-C com C . ([100]}@Vinzzz)
  3. .mm: pode misturar Objective-C com C++. Esta ponte é Objective-C++. (@Vinzzz ).
  4. .c: puro
  5. .cpp: pode misturar ++ & montagem (@Vality)
  6. .h: onipresente e ambíguo C, C++, objective-C ou objective-C++, então a resposta é depende.

Referências

 171
Author: SwiftArchitect, 2020-06-20 09:12:55

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.

 72
Author: Gian Luigi Romita, 2014-06-13 10:14:15

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;
}
 33
Author: Dan G, 2015-06-18 20:01:14

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/OpenCVSwiftStitch
 27
Author: foundry, 2014-06-04 19:04:59
Aqui está a minha tentativa de uma ferramenta de clang para automatizar a comunicação C++/swift. Você pode instanciar classes de C++ da swift, herdar da Classe C++ e até mesmo sobrepor métodos virtuais da swift.
Irá processar a Classe C++ que deseja exportar para a swift e gerar automaticamente a Ponte Objective-C/Objective-C++.

Https://github.com/sandym/swiftpp

 13
Author: Sandy, 2014-09-23 00:18:46

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.

 8
Author: Austin, 2014-06-04 16:35:51

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/.

 4
Author: Russj, 2014-12-03 13:05:05
Não, Não num único ficheiro.

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

 4
Author: James Mart, 2015-03-27 20:04:46

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;
}
// */
 2
Author: snake5, 2017-08-31 10:31:31
Um truque (de muitos) é aquele

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.

Mais uma vez, infelizmente, isto é apenas uma dica em todo o processo.
 2
Author: Fattie, 2020-06-20 09:12:55

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.

Ver http://www.swiftprogrammer.info/swift_call_cpp.html

 1
Author: Anatoli P, 2015-09-16 03:40:09

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

 1
Author: Ryan Heitner, 2016-06-20 13:24:18