【发布时间】:2014-12-04 04:00:20
【问题描述】:
我正在尝试使用 ctypes 在 python 中为他们的新闻组预训练向量包装谷歌的 word2vec。
我这里有一段代码:
void initialize(){
...
long long words, size;
char *fname = "GoogleNews-vectors-negative300.bin.gz";
strcpy(file_name, fname);
printf("%s\n", file_name);
f = fopen(file_name, "rb");
if (f == NULL) {
printf("Input file not found\n");
return -1;
}
fscanf(f, "%lld ", &words);
fscanf(f, "%lld", &size);
printf("size of words is %d\n", words);
...
}
当我从主函数调用此代码时,它运行良好。但是,当我将它编译为 .so 文件并从 ctypes 调用它时,单词总是为零。检查 ftell,我注意到 fscanf 不会向前移动文件指针,并且 fscanf 总是返回 0。它是一个二进制文件,所以我不确定 fscanf 在这里的工作除了将这个 3 GB 二进制文件转换为更多大量 .csv 并从那里读取。
如何解决这个问题?在这种情况下,避免 fscanf 的替代路线也可以工作。
【问题讨论】:
-
我不是 ctypes 方面的专家,但就字节数而言,它“理解”为
long long与 C 编译器所做的事情之间是否存在冲突?你可以检查docs.python.org/2/library/ctypes.html中的类型表,也许它可以帮助你。 -
@lord 我检查了 long long 的大小,它对应于 ctype 和我的机器上的 sizeof(long long) 的 8 个字节。我不明白这是否相关,因为执行纯粹是在 C 端。
-
@chux 正如我所说,fscanf 返回 0,这表明根据手册页表示早期失败,但我不确定为什么这只发生在来自 python 的调用期间。
-
@ArtisanV 对此感到抱歉。 IAC:当
fscanf()返回0时,使用int ch = fgetc(f);读取违规char,然后报告。我怀疑该文件是用二进制编写的(注意“rb”),代码需要使用fread()来读取二进制文件,而不是使用fscanf()来读取文本表示。 -
“GoogleNews-vectors-negative300.bin.gz”是压缩文件吗?如果是这样,那么有一种方法可以即时解压缩文件并将其输出作为输入到您的代码中。自从我这样做以来已经有一段时间了。 (使用标准输入很容易)