user2156649
user2156649

Reputation: 73

Swift access to C Struct

I am developing a OS X Swift app for parsing cvs files. It runs successfully in Objective-C. Then I changed to Swift and for performance improvements I developed the parse/import engine in C. It is 5 times faster as in Swift or Objective-C - nice. But I have trouble to exchange the data between C and Swift - especially with Struct:

BridgingHeader:

#include "ToolBoxC.h"

ToolBoxC.h:

void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings);

typedef struct {

                    char **headerArray;
                    int numberHeaderRows;
                    char **dateArray;
                    int numberDateRows;
                    int **valueArray;
                    char ***stringArray;
                    int numberValueRows;
                    int numberValueColums;
        } FileStruct;

typedef struct {

                    FileStruct fileContent[10000];
} FilesStruct;

struct FilesStruct filesContent;

ToolBoxC.c:

struct FileStruct {

    char **headerArray;
    int numberHeaderRows;
    char **dateArray;
    int numberDateRows;
    int **valueArray;
    char ***stringArray;
    int numberValueRows;
    int numberValueColums;
};

struct FilesStruct {

    struct FileStruct fileContent[10000];
};

void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings) {

// some stuff

    struct FileStruct fileContent;

    fileContent.headerArray = headerArray;
    fileContent.numberHeaderRows = numberHeaderRows;
    fileContent.dateArray = dateArray;
    fileContent.numberDateRows = numberDateRows;
    fileContent.valueArray = valueArray;
    fileContent.stringArray = stringArray;
    fileContent.numberValueRows = numberValueRows;
    fileContent.numberValueColums = numberValueColumns;

    filesContent.fileContent[numberFiles] = fileContent;

return;
}

All the parsed data are stored in struct FilesStruct filesContent. The parsing is started by calling the function loadFile() with parameters from Swift. That works fine. Also the parsing is OK. But how can I access to the data in struct FilesStruct filesContent from Swift?

Thanks, Matthias.

Upvotes: 2

Views: 1880

Answers (1)

Verticon
Verticon

Reputation: 2513

Try this:

ToolBoxC.h

#include <stdbool.h>

struct FileStruct {
    char **headerArray;
    int numberHeaderRows;
    char **dateArray;
    int numberDateRows;
    int **valueArray;
    char ***stringArray;
    int numberValueRows;
    int numberValueColums;
};

extern struct FileStruct **loadedFiles;

void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings);

ToolBoxC.c

#include <stdlib.h>
#include "ToolBoxC.h"

#define MaxFiles 10000

struct FileStruct **loadedFiles;

void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings) {

    static int nextIndex = 0;

    if (loadedFiles == 0)
        loadedFiles = malloc(MaxFiles * sizeof(*loadedFiles));

    struct FileStruct *file = malloc(sizeof(struct FileStruct));
    file->numberDateRows = xRow;

    loadedFiles[nextIndex++] = file;
}

Swift Test Method

func loadFilesTest() -> Void {
    for var i:Int32 = 0; i < 10; ++i {
        loadFile("", "", "", 0, 0, 0, i, 0, true)
    }
    for var j = 0; j < 10; ++j {
        let pointer = UnsafePointer<FileStruct>(loadedFiles[j])
        print("Number of date rows = \(pointer.memory.numberDateRows)")
    }
}

Upvotes: 2

Related Questions