0

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

我还在 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>

我在这里缺少什么?

4

1 回答 1

2

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

如果你有一个想要导入 Swift 的 C++ 头文件,你必须确保所有 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 年以来就没有认真使用它

于 2017-12-13T09:52:08.543 回答