如何在 cffi 中支持 64 位指针?
How to support 64 bits pointers in cffi?
我正在使用 cffi 将我的 Python 模块与 C 库连接。
我在 Linux 上一切正常,但我在 Mac OS X(Yosemite - 64 位)上遇到了困难。这是我写的一个显示问题的最小示例:
foo.h
#ifndef FOO_H
#define FOO_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void* mymalloc(size_t);
#ifdef __cplusplus
}
#endif
#endif
foo.cpp
#include "foo.h"
#include <cstdlib>
#include <cstdio>
void* mymalloc(size_t size) {
void* const result = ::malloc(size);
printf("%p\n", result);
return result;
}
生成文件
run: foo.py libfoo.dylib
DYLD_LIBRARY_PATH=. LIBRARY_PATH=. python foo.py
libfoo.dylib: foo.cpp foo.h
g++ -dynamiclib -o $@ $<
foo.py
import cffi
ffi = cffi.FFI()
ffi.cdef("""
void* malloc(size_t);
void* mymalloc(size_t);
""")
api = ffi.verify("", libraries=['foo'])
result = api.malloc(4)
print "malloc", result
result = api.mymalloc(4)
print "mymalloc", result
所以这里没什么特别的:一个简单的 mymalloc(size_t)
函数,它充当真实 malloc(size_t)
函数的包装器,并在返回之前显示生成的指针。
执行foo.py
(使用make run
)时,我看到了以下输出:
g++ -dynamiclib -o libfoo.dylib foo.cpp
DYLD_LIBRARY_PATH=. LIBRARY_PATH=. python foo.py
malloc <cdata 'void *' 0x7fdba0e01670>
0x7fdba0e00280
mymalloc <cdata 'void *' 0xffffffffa0e00280>
在 mymalloc(size_t)
的情况下,cffi 似乎以某种方式 truncated/modified 指针积分值:我得到 0xffffffffa0e00280
而不是预期的 0x7fdba0e00280
。这基本上是指针的值,但仅存储在 32 位上。 malloc(size_t)
具有完全相同的原型,但似乎由 cffi 正确处理,returns 64 位地址。
我不知道我在这里做错了什么。有人知道吗?
根据 official answer,我调用 verify()
的方式是假的。
正确的代码应该是:
import cffi
ffi = cffi.FFI()
code = """
void* malloc(size_t);
void* mymalloc(size_t);
"""
ffi.cdef(code)
api = ffi.verify(code, libraries=['foo'])
result = api.malloc(4)
print "malloc", result
result = api.mymalloc(4)
print "mymalloc", result
这确实产生了预期的结果!
我正在使用 cffi 将我的 Python 模块与 C 库连接。
我在 Linux 上一切正常,但我在 Mac OS X(Yosemite - 64 位)上遇到了困难。这是我写的一个显示问题的最小示例:
foo.h
#ifndef FOO_H
#define FOO_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void* mymalloc(size_t);
#ifdef __cplusplus
}
#endif
#endif
foo.cpp
#include "foo.h"
#include <cstdlib>
#include <cstdio>
void* mymalloc(size_t size) {
void* const result = ::malloc(size);
printf("%p\n", result);
return result;
}
生成文件
run: foo.py libfoo.dylib
DYLD_LIBRARY_PATH=. LIBRARY_PATH=. python foo.py
libfoo.dylib: foo.cpp foo.h
g++ -dynamiclib -o $@ $<
foo.py
import cffi
ffi = cffi.FFI()
ffi.cdef("""
void* malloc(size_t);
void* mymalloc(size_t);
""")
api = ffi.verify("", libraries=['foo'])
result = api.malloc(4)
print "malloc", result
result = api.mymalloc(4)
print "mymalloc", result
所以这里没什么特别的:一个简单的 mymalloc(size_t)
函数,它充当真实 malloc(size_t)
函数的包装器,并在返回之前显示生成的指针。
执行foo.py
(使用make run
)时,我看到了以下输出:
g++ -dynamiclib -o libfoo.dylib foo.cpp
DYLD_LIBRARY_PATH=. LIBRARY_PATH=. python foo.py
malloc <cdata 'void *' 0x7fdba0e01670>
0x7fdba0e00280
mymalloc <cdata 'void *' 0xffffffffa0e00280>
在 mymalloc(size_t)
的情况下,cffi 似乎以某种方式 truncated/modified 指针积分值:我得到 0xffffffffa0e00280
而不是预期的 0x7fdba0e00280
。这基本上是指针的值,但仅存储在 32 位上。 malloc(size_t)
具有完全相同的原型,但似乎由 cffi 正确处理,returns 64 位地址。
我不知道我在这里做错了什么。有人知道吗?
根据 official answer,我调用 verify()
的方式是假的。
正确的代码应该是:
import cffi
ffi = cffi.FFI()
code = """
void* malloc(size_t);
void* mymalloc(size_t);
"""
ffi.cdef(code)
api = ffi.verify(code, libraries=['foo'])
result = api.malloc(4)
print "malloc", result
result = api.mymalloc(4)
print "mymalloc", result
这确实产生了预期的结果!