在C中,我需要调用一些Swift代码,该代码接受输入字节数组并生成输出字节数组。
这在桥接报头中:
typedef void (*SwiftFunc)(const uint8_t* input, int inputLen, uint8_t** output, int* outputLen);
extern "C" void CFunc(SwiftFunc swiftFunc);下面是CFunc的C实现:
void CFunc(SwiftFunc swiftFunc) {
char* input = "Hello world";
int inputLen = strlen(input);
char* output = NULL;
int outputLen = 0;
swiftFunc(input, inputLen, &output, &outputLen);
// do something with the output here
}这是Swift的代码:
func swiftFunc(
input: Optional<UnsafePointer<UInt8>>,
inputLen: Int32,
output:Optional<UnsafeMutablePointer<
Optional<UnsafeMutablePointer<UInt8>>>>,
outputLen:Optional<UnsafeMutablePointer<Int32>>) -> Void {
let cfInput = CFDataCreate(kCFAllocatorDefault, input, CFIndex(inputLen))
let cfOutput = ... generate the output ...
How to pass the output buffer back to C?
}如何将输出缓冲区从Swift传递到C?假设涉及到双指针。
另外,Swift函数签名似乎非常冗长,这是意料之中的吗?我试着用?后缀代替Optional<>,但是编译器不喜欢它。
发布于 2018-08-25 03:00:34
您需要做的就是将UnsafeMutablePointer<UnsafeMutablePointer<UInt8>>的pointee属性设置为UnsafeMutablePointer<UInt8>的一个实例。使用您当前的方法,Swift函数负责分配与输出缓冲区相关的内存。
调用UnsafeMutablePointer<UInt8>.allocate(MemoryLayout<UInt8>.stride * outputLength)大致等同于调用malloc,在此用例中是必需的。使用正确的内存分配创建缓冲区后,从cfOutput初始化它的值。例如,如果cfOutput的类型为[UInt8],则可以执行以下操作:
for i in 0..<cfOutput.count {
buf[i] = cfOutput[i]
}在初始化输出缓冲区中的值之后,只需将output?.pointee设置为您刚刚分配和初始化的UnsafeMutablePointer<UInt8>。
以下是如何将输出缓冲区传递回C的示例。
func swiftFunc(input: UnsafePointer<UInt8>!,
inputLen: Int32,
output: UnsafePointer<UnsafePointer<UInt8>>?,
outputLen: UnsafePointer<UInt8>?) {
let cfInput = CFDataCreate(kCFAllocatorDefault, input, CFIndex(inputLen))
let cfOutput = // Generate your output.
let bufLen = // Determine output buffer length.
let buf = UnsafeMutablePointer<UInt8>.allocate(MemoryLayout<UInt8>.stride * bufLen)
// Initialize 'buf' with 'cfOutput' somehow.
output?.pointee = buf
outputLen?.pointee = Int32(bufLen)
}https://stackoverflow.com/questions/52008771
复制相似问题