草庐IT

framework swift C C++ 混编

hank009 2023-03-28 原文

最近在写一个 swiftframework 时遇到一个问题。
在此做个记录,方便自己也方便他人。
问题描述:
swift framework 中有用到一个 C++ 的算法,
因为 swift 不能直接调用 C++,只能通过 C 或者 OC 桥接调用。
在 纯 swift 项目中,在桥接文件中直接包含 C 或者 OC 头文件,即可混编。 可是在 framework 中不可以使用桥接头文件,只能使用 modulemap 代替桥接头文件。

具体步骤:

1.导入 C++ 文件到 framework

2.编写 swiftC++ 的桥接 C 函数

因为 swift 不能直接调用 C++,只能通过 C 或者 OC 桥接调用。在此我们选用 C 作为桥接。

image.png

#ifndef SPLineExt_h
#define SPLineExt_h

#ifdef __cplusplus
extern "C" {
#endif

double c_splineValue(const double *x,int x_len,
                   const double *y,int y_len,
                   double p_x);

#ifdef __cplusplus
}
#endif

#endif /* SPLineExt_h */

因为要用到的 C++ 代码在 SPLine.cpp 类文件中,所以上面写的 C 函数实现写在 SPLine.cpp 中。

double c_splineValue(const double *x,int x_len,
                   const double *y,int y_len,
                   double p_x){
    std::vector<double> v_x;
    for (int i = 0; i<x_len; i++) {
        v_x.push_back(x[i]);
    }

    std::vector<double> v_y;
    for (int i = 0; i<y_len; i++) {
        v_y.push_back(y[i]);
    }

    SPLine sp = SPLine(v_x, v_y);
    double d = sp(p_x);

    return d;
}

3.新建 module.modulemap 文件

更多 modulemap 语法

framework module VCBle {
   umbrella header "../VCBle.h"
   export *
   module * { export * }
   
   explicit module Spline_Private {
      header "../SPLineCPP/SPLineExt.h"
      export *
   }
}

4.设置 Xcode 中 modulemap path

Targets/Build Setting/ Module Map File

image.png

Targets/Build Setting/ Import paths

image.png

5. 测试调用 C++ 函数

在需要用到 C++ 函数的 swift 代码中测试下

import VCBle.Spline_Private

public func swift_getSplineValue() -> Double {
    let x:[Double] = [0.1, 0.4, 1.2, 1.8, 2.0]
    let y:[Double] = [0.1, 0.7, 0.6, 1.1, 0.9]
    let d = c_splineValue(x, Int32(x.count), y, Int32(y.count), 1.5)
    return d
}

测试打印结果:
spline value:%.f 0.9153451492537314

swift 完美调用了 c++ 代码!

参考文章

有关framework swift C C++ 混编的更多相关文章

  1. ruby - Ruby 2.2.0 中的混编比 2.1.5 慢 - 2

    我有一个复杂的对象my_object,我用它来编码编码(marshal)转储(我的对象)我已经在2.1.5p273和2.2.0中对调用该行100次的性能进行了基准测试,结果如下:2.1.5usersystemtotalrealMarshalDump7.3100000.1200007.430000(8.988470)MarshalDump7.5200000.0500007.570000(8.210356)MarshalDump7.6100000.0500007.660000(8.432685)2.2.0usersystemtotalrealMarshalDump26.4800000.15

  2. 解决Swift和OC在同一个Pods库中不能混编的问题 - 2

    1、Pods库用swift创建的,需要引用OC,用外部添加桥接文件TargetName-Bridging-Header.h,行不通的2、创建一个继承NSObject的public_header的OC类,把要引用的OC头文件添加到.h文件中;在.podspec文件中加入s.public_header_files='xxx/Classes/public_header.h'3、Pods组件库Classes目录下创建一个文件夹TestFolder,在文件夹中新建一个testfile.modulemap文件,并把文件内容设置成module test[system]{  header"xxxxx.h"  

  3. swift与OC混编之互相引用 - 2

    一、swift调用OCswift调用oc的代码,需要使用“桥接文件”,桥接文件基本上在你创建OC代码的时候会提示你创建,桥接文件里导入的是在swift代码中要使用到的OC代码。创建一个swift工程,然后再创建一个OC类。image.png此时会询问是否创建桥接文件,点击创建。桥接文件的配置路径在BuildSettings中搜索Swift。image.png只要路径正确,配置完成后,在桥接文件里引入swift代码中要使用的oc库即可。image.png需要使用的地方直接使用image.png如果桥接文件删掉了,此时创建一个header,并在BuildSettings设置好路径,然后按照上述操作

  4. Swift与OC混编 - 2

    调用OC文件image.png创建OC文件会自动生成xxxxxx-Bridging-Header.h的文件image.png只需要在xxxxxx-Bridging-Header.h文件中引入OC的头文件即可调用swift文件OC文件调用swift文件image.png在buildsetting->SwiftCompiler-General中的Objective-CGeneratedInterfaceHeaderName选项所对应的名字为xxxxx-Swift.h这个文件在工程列表中是没有的,但是我们可以直接在OC文件中导入该头文件image.png导入头文件后就可以调用swift文件了,但是s

  5. 解决Swift和OC在同一个Pods库中不能混编的问题 - 2

    1、Pods库用swift创建的,需要引用OC,用外部添加桥接文件TargetName-Bridging-Header.h,行不通的2、创建一个继承NSObject的public_header的OC类,把要引用的OC头文件添加到.h文件中;在.podspec文件中加入s.public_header_files='xxx/Classes/public_header.h'3、Pods组件库Classes目录下创建一个文件夹TestFolder,在文件夹中新建一个testfile.modulemap文件,并把文件内容设置成module test[system]{  header"xxxxx.h"  

  6. swift与OC混编之互相引用 - 2

    一、swift调用OCswift调用oc的代码,需要使用“桥接文件”,桥接文件基本上在你创建OC代码的时候会提示你创建,桥接文件里导入的是在swift代码中要使用到的OC代码。创建一个swift工程,然后再创建一个OC类。image.png此时会询问是否创建桥接文件,点击创建。桥接文件的配置路径在BuildSettings中搜索Swift。image.png只要路径正确,配置完成后,在桥接文件里引入swift代码中要使用的oc库即可。image.png需要使用的地方直接使用image.png如果桥接文件删掉了,此时创建一个header,并在BuildSettings设置好路径,然后按照上述操作

  7. Swift与OC混编 - 2

    调用OC文件image.png创建OC文件会自动生成xxxxxx-Bridging-Header.h的文件image.png只需要在xxxxxx-Bridging-Header.h文件中引入OC的头文件即可调用swift文件OC文件调用swift文件image.png在buildsetting->SwiftCompiler-General中的Objective-CGeneratedInterfaceHeaderName选项所对应的名字为xxxxx-Swift.h这个文件在工程列表中是没有的,但是我们可以直接在OC文件中导入该头文件image.png导入头文件后就可以调用swift文件了,但是s

  8. Flutter 混编错误 :Failed to package ********** Command PhaseScriptExecution failed with a nonzero ex... - 2

    将flutter模块嵌入iOS工程中,编译时报错Failedtopackage。。。。flutter代码路径。。。。。CommandPhaseScriptExecutionfailedwithanonzeroexitcode这是由于flutter项目代码中有错误所导致的Xcode中编译报错打开flutter项目看看代码什么地方报错,将问题修改后,重新运行iOS项目即可。文章持续更新中、希望对各位有所帮助、有问题可留言大家共同学习.

  9. Flutter iOS混编 解决flutter在iOS14+ debug模式上无法运行的问题 - 2

    iOS项目引入Flutter后,安装Debug包,打开Flutter界面会出现"IniOS14+,debugmodeFlutterappscanonlybelaunchedfromFluttertooling,IDEswithFlutterpluginsorfromXcode"问题。image.png解决办法如下:用[Xcode]打开工程项目,在BuildSettings的最下方找到User-Defined,点击+按钮,添加一个键为FLUTTER_BUILD_MODE,debug设置profile模式,release设置release模式。image.png

  10. Flutter 混编错误 :Failed to package ********** Command PhaseScriptExecution failed with a nonzero ex... - 2

    将flutter模块嵌入iOS工程中,编译时报错Failedtopackage。。。。flutter代码路径。。。。。CommandPhaseScriptExecutionfailedwithanonzeroexitcode这是由于flutter项目代码中有错误所导致的Xcode中编译报错打开flutter项目看看代码什么地方报错,将问题修改后,重新运行iOS项目即可。文章持续更新中、希望对各位有所帮助、有问题可留言大家共同学习.

随机推荐