Nis*_*sba 3 c++ bridge static-libraries swift
精简版:
如何将std::string(使用桥接从 .Swift 文件调用的 .cpp 函数返回的对象)转换为 Swift String?
长版:
我有一个用 C++ 编写的库,我必须使用 Swift 调用一些代码。我创建了一个桥,在我的 Xcode 项目中添加了两个文件:
一个桥接头,它允许 Swift 调用 C 函数(afaik Swift 不能直接调用 C++ 函数,所以它需要通过 C 函数)
//file bridgingHeader.h
const char * getLastOpenedFile();
Run Code Online (Sandbox Code Playgroud)
和一个 .cpp 文件,它可以在内部调用(当然)C++ 函数,并且可以用 extern "C" 定义 C 函数
//file wrapper.cpp
#include <string>
#include "my_library.hpp"
extern "C" const char * getStringFromLibrary()
{
const char * s = get_string_from_library().c_str();
return s;
}
Run Code Online (Sandbox Code Playgroud)
我可以使用 .swift 文件访问返回值
let myString = String(cString: getStringFromLibrary())
Swift.print(myString)
Run Code Online (Sandbox Code Playgroud)
放置断点检查s函数内部的值getStringFromLibrary()我可以看到字符串的内容,因此库中的函数被正确调用。
无论如何, .swift 文件会打印一些奇怪的符号而不是原始字符串。更改getStringFromLibrary()为以下
extern "C" const char * getStringFromLibrary()
{
return get_string_from_library().c_str();
}
Run Code Online (Sandbox Code Playgroud)
我的结果是 .swift 代码打印了真实字符串的前缀。这让我想到了一个内存问题:可能在getStringFromLibrary()退出时,std::string返回的对象get_string_from_library()被销毁,因此返回的指针指向的内存.c_str()不再可靠,这是为什么我从Swift.print().
std::string从 .swift 文件访问一个然后释放其内存的正确方法是什么?
您可以编写一个 Objective-C++ 包装器来处理 C++ 代码。
桥接头:
#include "Wrapper.hpp"
Run Code Online (Sandbox Code Playgroud)
包装器.hpp:
#ifndef Wrapper_hpp
#define Wrapper_hpp
#import <Foundation/Foundation.h>
#if defined(__cplusplus)
extern "C" {
#endif
NSString * _Nonnull getStringFromLibrary();
#if defined(__cplusplus)
}
#endif
#endif /* Wrapper_hpp */
Run Code Online (Sandbox Code Playgroud)
包装.mm:
#include "Wrapper.hpp"
#include <string>
#include "my_library.hpp"
NSString * _Nonnull getStringFromLibrary() {
return [NSString stringWithUTF8String:get_string_from_library().c_str()];
}
Run Code Online (Sandbox Code Playgroud)
SWIFT代码:
print(getStringFromLibrary())
Run Code Online (Sandbox Code Playgroud)
[NSString stringWithUTF8String:]将缓冲区的内容复制到一些内部存储中,ARC 管理释放它。您无需定义free_something().
| 归档时间: |
|
| 查看次数: |
1593 次 |
| 最近记录: |