Swift、C和C 混编(二)

     上一篇写了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地址

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值