将C ++代码桥接到我的快速代码中。XCode中哪些基于c语言的文件扩展名是什么?

J.D*_*Doe 2 c++ xcode objective-c ios swift

作为Swift编码器,我对事物c方面的明显碎片感到困惑。不知何故,有Objective-C,Objective-C ++,c和c ++,它们都具有.h,.hpp,.m,.cpp等文件扩展名,但是我找不到关于哪个扩展名指向哪种文件类型的详尽文档。 XCode(尽管我相当确定c ++应该是.hpp和.cpp)。

这种混乱使我陷入困境,在尝试向快速代码公开C ++类时,我对自己的工作一无所知。让我解释一下我的策略。

我有一个由我修改过的XCode自动生成的桥接文件

桥接头

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//

#include <stdio.h>
#include <stdlib.h>

int* main1() {
    int *num;

    num = (int *)malloc(1000 * sizeof(int));
    for (int i = 0; i < 10; i++) {
        num[i] = i;
    }
    num[10] = 10;
    free(num);
    return num;
}
Run Code Online (Sandbox Code Playgroud)

如果我解释正确,那么XCode会将其视为Objective-C代码的头文件。确实,此功能可以迅速发挥作用并按预期工作。

然后,我创建了另一个文件,因为如果我尝试在该文件中导入我的c ++代码,它将尝试像objective-c一样编译它,但效果不佳。我相信该文件将是此标头的实现,并且我被告知这将是导入我的c ++代码的安全地方。

还有 Bridging-Header.m

#ifndef Bridging_Header_h
#define Bridging_Header_h
#import "Bridging-Header.h"
#import "rectangle.hpp"

int main2() {
    Rectangle* r = new Rectangle();
    return 2;
}

#endif /* TryPost_Bridging_Header_h */
Run Code Online (Sandbox Code Playgroud)

我希望XCode将此代码视为Objective-c ++代码,因此允许我安全地导入我的c ++代码,我认为它会自动链接到其相应的标头,因为如果我尝试从其他文件中导入它,则会导致导入周期导致大量问题。

但是,这些假设必定是错误的,因为该代码似乎甚至没有被编译。Swift没有看到该功能main2没有立即显示出来。

还有Rectangle.hpp

#ifndef rectangle_hpp
#define rectangle_hpp

#include <stdio.h>

int main3() {
    return 3;
}
class Rectangle {
    int main();
};

#endif /* fancy_hpp */
Run Code Online (Sandbox Code Playgroud)

我相信XCode应该将此解释为C ++代码。也有

矩形文件

#include "rectangle.hpp"

int Rectangle::main() {
    std::cout << "Hello world!";
    return 99;
}

int main4() {
    return 99;
}
Run Code Online (Sandbox Code Playgroud)

这些似乎都没有被编译。

我很困惑,因为我什至不知道如何开始处理所有这些语言之间的导入,也不知道如果我希望编译器自动将它们视为某种语言时应该给文件命名。如何在调用时使Rectangle类迅速暴露,甚至打印出“ Hello World”(即使我怀疑是否可以从c ++进行打印)。

老实说,我并不真正在意main2它的功能只是出于测试目的,因为我认为我需要该文件来获取我的c ++。如果它不包含在最终项目中,我不会介意。main1main2main4Rectangle都是重要不过。

Sun*_*nil 5

您不能直接使用c/c++代码,swift因为类型系统不同。Objective c/c++是混合的,意味着它理解c/c++类型和swift类型。要使用Rectangle c++类,可以将其包装在一个objective c/c++类中,然后将objective c/c++<Project>-Bridging-Header.hpp文件导入文件以将其公开给Swift

Swift默认情况下会处理所有带有扩展名的文件-

*.m - as objective c files
*.mm - as objective c++ files
*.hpp - as (objective) c/c++ header files
*.cpp - as c++ files
*.c - as c files
Run Code Online (Sandbox Code Playgroud)

现在来看您的示例,如果我理解正确,则想在中使用c ++类(例如RectangleSwift。这是解决方案的分层视图。

+----------------------------------+
|  Rectangle (c++)                 |
+----------------------------------+
|  RectangleWrapper (objc++)       |
+----------------------------------+
|  Bridging header                 |
+----------------------------------+
|  Swift                           |
+----------------------------------+
Run Code Online (Sandbox Code Playgroud)

土著阶级

// Rectangle.h
class Rectangle {
  public:
   void draw();
}

// Rectangle.cpp
void Rectangle::draw() {
  cout << "draw rectangle" << endl;
}
Run Code Online (Sandbox Code Playgroud)

objc ++包装器

// RectangleWrapper.hpp
@interface RectangleWrapper : NSObject {
@private
  void* rect;
}
- (RectangleWrapper*) init;
- (void) draw;
@end

// RectangleWrapper.mm
#import "Rectangle.h"
@implementation RectangleWrapper

- (RectangleWrapper*) init {
  rect = (void*)new Rectangle;  // create c++ class instance
  return self;           // return objc++ instance
}

- (void) draw {
  Rectangle* r = (Rectangle*)rect;
  r->draw();  // call c++ method
}

@end
Run Code Online (Sandbox Code Playgroud)

桥接头

只需将objc ++头文件导入,即可公开您的目标c ++类,从而迅速了解世界Bridging-Header.hpp

// Bridging-Header.hpp
#import "RectangleWrapper.hpp"
Run Code Online (Sandbox Code Playgroud)

迅速

现在,只需将目标c ++ RectangleWrapper类用作任何其他swift类即可。

// use-rectangle.swift
let rect = RectangleWrapper()
rect.draw()
Run Code Online (Sandbox Code Playgroud)

在github上查看完整的代码


归档时间:

查看次数:

1164 次

最近记录:

8 年,2 月 前