c - 在 Swift 中调用的 C 结构在调用本机代码时未更新
问题描述
我有一个 C 结构:
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*);
};
像这样初始化:
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;
}
我在处理文件中的行的循环中调用 parse 函数。parse 函数运行并根据其输出更新结构对象的一些属性。
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";
}
在 Swift 中,我这样做:
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)
}
}
在 C 中调用解析器代码时,它可以正常工作。
但是当从 Swift 调用时,我注意到结构对象,即fs
属性在 while 循环的每次迭代中都没有更新。
问题:
如何确保在调用 C 代码时更新结构的属性。
从 Swift 调用的结构的副本是否与 C 使用的不同?
解决方案
从 Swift 调用的结构的副本是否与 C 使用的不同?
确切地。这个
let fs: FastSax = ptr!.withMemoryRebound(to: FastSax.self, capacity: 1) {
$0.pointee
}
是复制 . 所指向的结构的一种(复杂)方法ptr
。然后
let out = fs.parse(ptr , line)
更新指向的结构ptr
(这是之前获得的默认结构)而不是指向的结构fs
。
你可能想要的只是
let out = fastSax!.pointee.parse(fastSax, line)
假设fastSax
不是nil
。如果不能保证,请使用可选绑定或可选链接。ptr
和fs
变量不是必需的。
推荐阅读
- arrays - 元子中的空条件?
- amazon-web-services - 以非 root 用户身份在脚本中从 AWS ECR 获取 Docker 容器
- c++ - 我可以像这样在 C++ 中转换:int ('a') 吗?
- c# - 如何进行单元测试 - 压缩文件
- regex - 如何删除带有文本的括号和字符串末尾的一些文本
- hana - 为什么增量加载会向 HANA 插入重复记录?
- c# - 控制台光标前的 Cosmos C# 文本
- gitops - 如何将 UI 和核心原理配置作为代码使用?
- sql - 需要帮助使用 Flask 应用程序访问 Jinja 中的 Python 字典值
- python - 在尝试使用 PyQt UI 运行代码时使用 selenium 和 python 问题 i