Swift、C和C 混编(二)

本秂侑毒 提交于 2019-12-02 05:06:47

     上一篇写了Swift、C、C++混合调用的情况,对于这些简单的调用我想大家已经有了基本的技能了。那么接下来我们在来看看怎么在swift里使用c数组。对于这个数组。对于指针我们可以直接赋值,并且也可以直接读取,那么对于数组呢,也是这样么。我们来看看。怎么样读取。

测试环境:
xcode: 11.1 swift 版本: 5.0

我们先创建一个工程命名为SwiftDemo。然后我们创建一个C++文件命名为CPersomModel。在.hpp里定义下面的代码:

struct CPersonModel {
    char *name;
    char birthday[20];
    int age;
};
struct CPersonModel* createModel();

在实现的.cpp里我们实现如下:

struct CPersonModel* createModel(){
    CPersonModel *model = new CPersonModel();
    
    
    
    model->name = new char();
    const char *name = "张三";
    stpcpy(model->name, name);
    
    const char *birthday = "1990-05";
    stpcpy(model->birthday, birthday);
    
    
    model->age = 30;
    return model;
}

然后我们创建一个CHeader.h文件并且加上一下代码:

#ifdef __cplusplus
extern "C" {
#endif
   struct CPersonModel* readPersonModel();

#ifdef __cplusplus
}
#endif

最后在实现这个接口的函数。在.cpp里加上:

struct CPersonModel* readPersonModel() {
    CPersonModel *model = createModel();
    return model;
}

然后我们在桥接文件里导入这个CHeader.h文件。我们就可以直接是用来。

接下来我们在我们的.swift文件里调用我们刚才写的函数:

let modelPoint = readPersonModel();
let model = modelPoint?.pointee;
let name = model?.name;
let birthday = model?.birthday;
let age = model?.age;
let swiftName = String(cString: name!);
print("name =\(swiftName),\(birthday),age \(age)");

接下来我们会发现下列情况:

name和birthday不一样,转成我们swift的字符串的方法也不一样。对于name指针,Swift为我们转成了指针,通过swfit我们可以很好的转成字符串。

如下:

String(cString: <#T##UnsafePointer<CChar>#>)

刚好也是接受一个指针。但是对于birthday这个属性我们这里就不能直接这么使用了。网上也有一个方法。可以把他转成我们swift的字符串。

我们先使用一下: 

func convertString(any: Any) -> String {
    
    let mirror = Mirror(reflecting: any);
    let resutStrl = mirror.children.reduce("") { (result, arg1) -> String
in
        guard let intValue = arg1.value as? Int8, intValue > 0 else{
            return result;
        }
        let strl = String(UnicodeScalar.init(UInt8(intValue)));
        return result + strl;
    }
    return resutStrl;
    
}

经过测试没有问题。但是呢如果把生日改成 1990年05月,我们再试的话就会出现一连串数字没有了年和月,经过分析,发现intValue的值是负数小于0的。所以他就不能缺少信息了。如果我们去掉判断intValue > 0 ,那么我们就会出错,那么我们很显然是对于有中文的字符串是不能使用这个方法的。那么我们改怎么做呢。

我们是不是可以把birthday转换成name的形式呢,如果我们能转换成name的形式,那我们就可以直接使用第一个函数来做了,第一个是可以处理中文的,我们现在的问题是怎么转换成name指针形式。

最终我找到一个方法可以转成指针的形式,那么我们直接上代码:

static func convertCharArray(any: Any) -> String {
    
    let mirr = Mirror(reflecting: any);
    let count = mirr.children.count;
    let point = UnsafeMutablePointer<Int8>.allocate(capacity: count);
    for (idx,item) in mirr.children.enumerated() {
        if let value = item.value as? Int8 {
            point[idx] = value;
        }
    }
    let result = String(cString: point);
    point.deallocate();
    return result;
}

这样就完美解决了中文显示的问题。那么又有一个新的问题出来了,对于指针name我们可以直接赋值,那么对与像birthday这样的数组我们改怎么办呢,在swift里怎么给他赋值呢。对于这个问题如果有人有很好的办法,不妨先留言讨论一下。

到此主要的问题已经解决,最后demo是不能少的,demo地址

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!