Hi @eryksun和Python专家:
我试图使用以下命令将dll文件导入到cffi中:
from cffi import FFI
ffi=FFI()
lib=ffi.dlopen('ATC3DG.DLL')从前面关于C型的一个问题中,我知道DLL都是cdecl (感谢@eryksun的提示),我能够以以下方式访问它的函数:
from ctypes import *
lib=windll.LoadLibrary('ATC3DG.DLL')
lib._InitializeBIRDSystem然而,我不知道在cffi中将采取什么类似的行动。lib._InitializeBIRDSystem在ctype下工作,而不是cffi。有什么建议吗?
谢谢你调查这个,
埃里克
发布于 2013-09-13 09:02:31
atc3dg.dll导出的符号使用前导下划线,这在cdecl中是不常见的。您必须在ffi.cdef中使用的定义中添加下划线,就像对ctype一样。
import cffi
ffi = cffi.FFI()
ffi.cdef('''
enum MESSAGE_TYPE
{
SIMPLE_MESSAGE, // short string describing error code
VERBOSE_MESSAGE, // long string describing error code
};
int _InitializeBIRDSystem(void);
int _GetErrorText(
int errorCode,
char *pBuffer,
int bufferSize,
enum MESSAGE_TYPE type
);
''')
lib = ffi.dlopen('atc3dg.dll')
buf = ffi.new('char[100]')
err = lib._InitializeBIRDSystem()
lib._GetErrorText(err, buf, len(buf), lib.SIMPLE_MESSAGE)
print(ffi.string(buf).decode('ascii'))
# output:
# System : No BIRDs were found anywhere如果配置了C编译器,则可以使用ffi.verify()。我在cffi方面不是很有经验(还没有,但看起来很有希望),所以,请稍加考虑。
我不得不对头球做一个小小的改动。在COMMUNICATIONS_MEDIA_PARAMETERS的定义中,第500行需要按以下方式添加enum:
enum COMMUNICATIONS_MEDIA_TYPE mediaType;此外,就像FYI一样,编译器打印了一些警告,比如“从'unsigned __int64‘到'unsigned short’的转换,可能会丢失数据”。在为扩展模块生成的源代码中,我还没有对此进行跟踪。
import os
import cffi
import subprocess
pth = os.path.abspath(os.path.dirname(__file__))
os.environ['PATH'] += ';%s' % pth
# preprocess: modify this for your compiler
# Using Microsoft's cl.exe that comes with VC++.
# cdef chokes on __declspec, so define DEF_FILE.
cmd = 'cl.exe /DDEF_FILE /EP %s' % os.path.join(pth, 'atc3dg.h')
hdr = subprocess.check_output(cmd, universal_newlines=True)
ffi = cffi.FFI()
ffi.cdef(hdr)
# using __declspec(dllimport) links more efficiently,
# but skipping it still works fine
lib = ffi.verify(hdr, library_dirs=[pth], libraries=['atc3dg'])
buf = ffi.new('char[100]')
err = lib.InitializeBIRDSystem()
lib.GetErrorText(err, buf, len(buf), lib.SIMPLE_MESSAGE)
print(ffi.string(buf).decode('ascii'))
# output:
# System : No BIRDs were found anywhere从好的方面来说,这种方法避免了前面的下划线。这是链接器在编译扩展模块时处理的ABI细节。
https://stackoverflow.com/questions/18777251
复制相似问题