首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将CFData传递给C char**?

如何将CFData传递给C char**?
EN

Stack Overflow用户
提问于 2018-08-25 00:51:51
回答 1查看 357关注 0票数 1

在C中,我需要调用一些Swift代码,该代码接受输入字节数组并生成输出字节数组。

这在桥接报头中:

代码语言:javascript
复制
typedef void (*SwiftFunc)(const uint8_t* input, int inputLen, uint8_t** output, int* outputLen);

extern "C" void CFunc(SwiftFunc swiftFunc);

下面是CFunc的C实现:

代码语言:javascript
复制
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的代码:

代码语言:javascript
复制
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<>,但是编译器不喜欢它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-25 03:00:34

您需要做的就是将UnsafeMutablePointer<UnsafeMutablePointer<UInt8>>pointee属性设置为UnsafeMutablePointer<UInt8>的一个实例。使用您当前的方法,Swift函数负责分配与输出缓冲区相关的内存。

调用UnsafeMutablePointer<UInt8>.allocate(MemoryLayout<UInt8>.stride * outputLength)大致等同于调用malloc,在此用例中是必需的。使用正确的内存分配创建缓冲区后,从cfOutput初始化它的值。例如,如果cfOutput的类型为[UInt8],则可以执行以下操作:

代码语言:javascript
复制
for i in 0..<cfOutput.count {
    buf[i] = cfOutput[i]
}

在初始化输出缓冲区中的值之后,只需将output?.pointee设置为您刚刚分配和初始化的UnsafeMutablePointer<UInt8>

以下是如何将输出缓冲区传递回C的示例。

代码语言:javascript
复制
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)
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52008771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档