Я использую cffi для интерфейса моего модуля Python с C-библиотекой.
У меня все отлично работает на Linux, но мне тяжело с Mac OS X (Yosemite — 64 бита). Вот минимальный пример, который я написал, который показывает проблему:
#ifndef FOO_H
#define FOO_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void* mymalloc(size_t);
#ifdef __cplusplus
}
#endif
#endif
#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 $@ $<
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 как-то урезал / изменил целочисленное значение указателя: получаю 0xffffffffa0e00280
вместо ожидаемого 0x7fdba0e00280
, В основном это значение указателя, но оно хранится только в 32 битах. malloc(size_t)
который имеет точно такой же прототип, как представляется, правильно обрабатывается cffi и возвращает 64-битный адрес.
Я в растерянности, пытаясь найти то, что я делаю не так здесь. У кого-нибудь есть подсказка?
По словам официальный ответ, мой способ звонить 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
Какие значения дают ожидаемый результат!