I have a C Struct:
struct FastSax {
int parseErrorType;
int parserStatus;
int cacheIndex;
char* input;
int (* findOpen)(FastSax *, int);
int (* findClose)(FastSax *, int);
void (* print)(char *);
char* (* parse)(FastSax* , const char*);
};
Initialized like this:
FastSax* getDefault() {
FastSax *sax = malloc(sizeof (FastSax));
sax->cacheIndex = -1;
sax->findOpen = &findOpen;
sax->findClose = &findClose;
sax->parse = & parse;
sax->hasMoreTokens = &hasMoreTokens;
sax->fetchNextToken = &fetchNextToken;
sax->print = &print;
sax->parseErrorType = PARSE_ERROR_NONE;
sax->parserStatus = PARSE_STATUS_INSUFFICIENT_DATA;
sax->input = malloc(50 * sizeof (char));
strncpy(sax->input, "", 10);
sax->input[strlen(sax->input)] = '\0';
return sax;
}
I am calling the parse function in a loop that processes lines from a file. The parse function runs and based on its output, updates some properties of the struct object.
char* parse(FastSax* fs , const char *freshData) {
//parse operations on freshData
fs.cacheIndex = strlen(freshData);
fs.parserStatus = 4;
/**Parser code here**/
//not a constant string
return "the-result-of-the-parse";
}
In Swift, I do:
class ParserClient{
let fastSax = getDefault()
func parse(line: String) -> Int{
let ptr = fastSax
var status:Int32 = -1
let fs: FastSax = ptr!.withMemoryRebound(to: FastSax.self, capacity: 1) {
$0.pointee
}
let out = fs.parse(ptr , line)
//consume the first token
if fs.parseErrorType == PARSE_ERROR_NONE{
var token = String(cString: out)
self.delegate.endEntry(entry: token)
while true {
var _token = String(cString: fs.parse(ptr ,""))
Log.out("\(_token) , parser-status: \(fs.parserStatus)")
if fs.parserStatus == PARSE_STATUS_OK {
self.delegate.endEntry(entry: _token)
}else{
break
}
}
}else{
Log.out("Error: parser-status: \(fs.parserStatus) , error-type: \(fs.parseErrorType)")
}
return Int(fs.parserStatus)
}
}
When the parser code is invoked in C, it works fine.
But when called from Swift, I noticed that the struct object ie fs
properties were not being updated on each iteration of the while loop.
Question:
How do I make sure that the struct's properties are updated when it calls C code.
Is the copy of the struct invoked from Swift different from the one being used by C?
Is the copy of the struct invoked from Swift different from the one being used by C?
Exactly. This
let fs: FastSax = ptr!.withMemoryRebound(to: FastSax.self, capacity: 1) {
$0.pointee
}
is a (complicated) way of making a copy of the struct pointed to by ptr
. Then
let out = fs.parse(ptr , line)
updates the structure pointed to by ptr
(which is the default structure obtained before) and not the structure pointed to by fs
.
What you probably want is simply
let out = fastSax!.pointee.parse(fastSax, line)
assuming that fastSax
is not nil
. Use optional binding or optional chaining if that is not guaranteed. The ptr
and fs
variables are not needed.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.