我可以直接在Swift中使用C++吗?

3
我希望创建一个iOS和Android原生应用程序(我以前使用过Xamarin,但不想再使用它),因此我的下一个选择是编写C++共享代码,可以在两个平台上本地编译。
现在我想知道是否可以直接从Swift中使用C++。我找到的唯一解决方案是创建Objective-C++包装器,并通过桥接头公开它,但我不想有这种额外开销。
Swift是否计划支持这一点?或者有没有其他方法可以跳过Objective-C++步骤?

相关问题:https://dev59.com/DGAg5IYBdhLWcg3wBXOs - Ahmad F
可能是Can I mix Swift with C++? Like the Objective - C .mm files的重复问题。 - Kristopher Johnson
3个回答

3

目前不支持这个功能。从Swift代码中与C++代码通讯的方法只有两种:

  1. 使用Objective-C++将你的C++代码封装在ObjC中,就像你已经找到的那样。

  2. 利用C++大部分兼容C的事实,Swift可以调用C,为你的C++类编写一个C包装器,并从Swift中使用它。一种常见方法是:

cppwrapper.h

struct MyCppClass; // In C++ class and struct are the same, so this looks like a C struct to C, and as long as you don't look inside it, you can use pointers to it in C code.

extern "C" { // Tell C++ to turn off overloading based on type so it's C-compatible.

struct MyCppClass* MyCppClass_new( int firstParam );
void MyCppClass_delete( struct MyCppClass* inThis );
void MyCppClass_setFirstParam( struct MyCppClass* inThis, int firstParam );

} // extern "C"

cppwrapper.cpp

#include "cppwrapper.h"
#include "MyCppClass.hpp"    

extern "C" MyCppClass* MyCppClass_new( int firstParam )
{
    return new MyCppClass( firstParam );
}

extern "C" void MyCppClass_delete( MyCppClass* inThis )
{
    delete inThis;
}

extern "C" void MyCppClass_setFirstParam( struct MyCppClass* inThis, int firstParam )
{
    inThis->SetFirstParam( firstParam );
}

您甚至可以定义一个MyCppClassSwiftWrapper,其中包含一个类型为COpaquePointer的实例变量,用于存储C++对象。该类将在其构造函数中调用MyCppClass_new,在其析构函数中调用MyCppClass_delete,并且将包含一个围绕MyCppClass_setFirstParam的包装器,该包装器使用COpaquePointer作为其inThis参数。
我曾经写过一个(非常原始的)实用程序,可以让您标记C++头文件,并自动生成简单的C和Swift包装器(https://github.com/uliwitness/cpptoswift/),但它无法处理模板,您可能还需要添加更多的类型映射。它还不能正确地处理传递/返回C++对象。
还有https://github.com/sandym/swiftpp/,它做得更好,但我认为它仍然在其包装器下使用Objective-C,但至少您不必自己编写它。

0

我创建了一个Objective-C++框架,可以帮助简化这种桥接:CXXProxyKit。请看一下!


-1
如果您在 Bridging-Header.h 中将 C++ 头文件设置为 C 兼容,那么您就可以在 Swift 项目中无缝使用它。
#ifndef Bridging_Header_h
#define Bridging_Header_h

#import <Foundation/Foundation.h>
#include "CPlusPlusHeader.h"


#endif /* Bridging_Header_h */

有什么陷阱吗?我不知道这是可能的。 - vrwim
关键是要创建一个 Objective-C 桥接头文件,其中包含被标记为 C 兼容的 C++ 头文件,并使用 extern "C" {} 技巧。 - zero3nna
3
请注意,这只允许您调用“extern "C"`函数并使用与C兼容的类型。您不能直接使用C++类或其他非C++兼容功能。 - Kristopher Johnson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接