【问题标题】:cannot use namespace and cannot include standard C++ library in my .h files不能使用命名空间,也不能在我的 .h 文件中包含标准 C++ 库
【发布时间】:2017-12-13 08:20:55
【问题描述】:

我正在为我的 Swift 项目使用来自 https://www.surina.net/soundtouch/sourcecode.html 的 C++ 音频处理库

我还在 Projects-targets-build 阶段的编译源中包含了这些 cpp 文件。

当我尝试在桥接头中导入所有库头文件时

#import "SoundTouch.h"

编译时出错

Unknown type of name 'namespace' in STTypes.h
'stdexcept' file not found

我在头文件中使用命名空间

namespace soundtouch { ... } 

我不能同时使用几个标准库,比如字符串

#include <stdexcept>
#include <string>

我在这里缺少什么?

【问题讨论】:

  • 是的,我知道 Swift 不能导入 C++,所以我必须导入 C++ 包装器的头文件,对吗?例如,我有 SoundTouch.cpp ,但我也有 SoundTouch.h 作为包装器。所以下一步是在我的桥接头中导入 SoundTouch.h 文件,以确保 Swift 可以使用它
  • 如果您导入“SoundTouch.h”,那么“SoundTouch.h”不得(直接或间接)包含任何 C++。它必须是纯 C 接口。
  • 你需要写一个不依赖“SoundTouch.h”的C接口。
  • 所以,在这个例子中github.com/rspeyer/soundtouch 我不能直接将那些头文件用于我的桥接头?下一步是我必须创建一个新的目标 C 头文件来包装我的 C++ 文件 (SoundTouch.h) 的头文件?

标签: c++ objective-c swift xcode9 soundtouch


【解决方案1】:

即使在头文件中,Swift 也不理解 C++。 C 没有命名空间,所以当 Swift 编译器遇到 namespace 这个词时,它会像 C 编译器一样认为它是一个变量的名称。但这还不是全部。 Swift 也不会理解其他 C++ 关键字,例如 class,也不会理解 C++ 样式名称修改,即使它自己进行名称修改,也不会理解 export "C" { ... }

如果你有一个 C++ 头文件想要导入到 Swift 中,你必须确保所有的 C++ 内容都被 #ifdef __cplusplus 隐藏,就像你在 C 程序中包含头文件一样。此外,所有函数声明都需要为 extern "C" 才能禁用名称修改。

你需要一个类的替代声明,你可以使用void* 或者我发现一个不完整的struct 类型工作得很好,你需要创建C 包装函数来调用类中定义的函数。像下面这样的东西可能会起作用(我还没有测试过)。

#if defined __cplusplus
extern "C" {
#endif

#if defiend __cplusplus

class Foo
{
    void bar(int c);
}
#endif
struct FooHandle;

void Foo_bar(struct FooHandle* foo, int c);

#if defined __cplusplus
}
#endif

您需要在 C++ 文件中定义 shim 函数

#include MyHeader.h

void Foo_bar(struct FooHandle* foo, int c)
{
    ((Foo*) foo)->bar(c);
}

抱歉,如果我弄错了 C++,我自 1998 年以来就没有认真使用过它

【讨论】:

  • 所以我必须重写 SoundTouch 库中的所有 .h 文件?大约有 14 个文件,如果他们发布了新版本,我必须为新版本再次重写?
  • @calvinsugianto 不一定。我会为您要使用的操作编写一个带有 C 函数的 shim .h 文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2022-11-27
  • 1970-01-01
  • 2020-04-03
  • 2021-11-06
相关资源
最近更新 更多