上一篇写了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地址。
来源:https://blog.csdn.net/yaojinhai06/article/details/102715402