Swift, C and c mixed

     Last article Write the mixed calls of swift, C and C + +. I think you have basic skills for these simple calls. So let's see how to use C array in swift. For this array. For pointers, we can assign values directly and read them directly. For arrays, so can we. Let's see. How to read.

Test environment:
xcode: 11.1 swift version: 5.0

Let's first create a project named SwiftDemo. Then we create a C + + file named CPersomModel. Define the following code in. hpp:

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

In the implemented. cpp, we implement the following:

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

Then we create a header. H file and add the following code:

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

#ifdef __cplusplus

Finally, the function of this interface is implemented. In. cpp, add:

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

Then we import the header. H file into the bridge file. We can use it directly.

Next, we call the function we just wrote in our. swift file:

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)");

Next we will find the following:

Name and birthday are different, and the way to convert our swift string is also different. For the name pointer, swift turns it into a pointer for us, and we can turn it into a string through swfit.

As follows:

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

It also happens to accept a pointer. But we can't use birthday directly. There is also a way online. You can turn it into our swift string.

Let's use it first:

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

No problem after testing. However, if we change the birthday to May 1990, we will try again, and there will be a series of numbers without year and month. After analysis, it is found that the value of intValue is negative and less than 0. So he can't be short of information. If we remove the judgment intValue > 0, then we will make an error. Obviously, we cannot use this method for strings with Chinese characters. So how can we do it?

Can we convert birthday to name? If we can convert birthday to name, we can use the first function directly. The first one can deal with Chinese. How can we convert birthday to name?

Finally, I found a method that can be converted to the form of a pointer. Then we directly went to the code:

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);
    return result;

This perfectly solves the problem of Chinese display. Then a new problem arises. For pointer name, we can assign values directly. What should we do with arrays like birthday? How can we assign values to them in swift? If someone has a good way to solve this problem, please leave a message to discuss it.

The main problem has been solved. In the end, demo is indispensable. demo address.


Tags: Swift xcode less

Posted on Wed, 23 Oct 2019 20:30:41 -0700 by rahulephp