ctypes load a dll without error message, but nothi

2019-03-04 23:25发布

问题:

I tried to use windll.LoadLibrary in ctypes to import a dll file into python. Though there wasn't any error message, none of the functions listed in the header file seemed to be successfully loaded. I wonder if there is anything wrong with the dll file, or I have used the windll.LoadLibrary method incorrectly.

The dll and header files can be downloaded from the following link: http://www.cc.ncu.edu.tw/~auda/ATC3DG.rar

The python commands I used was:

from ctypes import * 
libc=windll.LoadLibrary('ATC3DG.DLL')

The results can be viewed from the following link, which shows dir(libc) does not give me any functions or variables listed in ATC3DG.h:

http://www.cc.ncu.edu.tw/~auda/ATC3DG.jpg

I am using python 2.7.3 (32-bit), and ipython 0.13.1 on a windows 7 (64-bit) platform.

thanks,

Erik Chang

回答1:

They don't show up when you use dir unless you've already accessed the function. For example:

In [98]: from ctypes import cdll

In [99]: libc = cdll.LoadLibrary('libc.so.6')

In [100]: dir(libc)
Out[100]:
['_FuncPtr',
 '__class__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__getattr__',
 '__getattribute__',
 '__getitem__',
 '__hash__',
 '__init__',
 '__module__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 '_func_flags_',
 '_func_restype_',
 '_handle',
 '_name']

In [101]: libc.printf
Out[101]: <_FuncPtr object at 0x65a12c0>

In [102]: dir(libc)
Out[102]:
['_FuncPtr',
 '__class__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__getattr__',
 '__getattribute__',
 '__getitem__',
 '__hash__',
 '__init__',
 '__module__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 '_func_flags_',
 '_func_restype_',
 '_handle',
 '_name',
 'printf']

You can see why this happens by looking at the CDLL.__getitem__ and CDLL.__getattr__ methods:

class CDLL(object):
    # ...

    def __getattr__(self, name):
        if name.startswith('__') and name.endswith('__'):
            raise AttributeError(name)
        func = self.__getitem__(name)
        setattr(self, name, func)
        return func

    def __getitem__(self, name_or_ordinal):
        func = self._FuncPtr((name_or_ordinal, self))
        if not isinstance(name_or_ordinal, (int, long)):
            func.__name__ = name_or_ordinal
        return func