list exported functions from dll with ctypes

Is there any way to know which functions are exported from the dll through python foreign function library ctypes?

And if possible to know details about the exported functions through ctypes.

If yes, could someone provide a snippet of code?


Solution 1:

I don't think ctypes offers this functionality. On Windows with visual studio:

DUMPBIN -EXPORTS XXX.DLL

Or for mingw on windows:

objdump -p XXX.dll

Solution 2:

If you are on Linux, there is a handy utility nm to list the content of a shared library (there is always a handy utility on Linux, especially for C stuff).

Here is the question about it.

You use it with the -D flag: nm -D ./libMyLib.so

Solution 3:

In general, this is not possible, because, again in general, dynamically loaded libraries do not carry the meta-information you require. It may be possible to obtain that information in certain special cases through system-specific ways, but ctypes itself does not fetch that information. You can record such info via ctypes (see e.g. the restype and argtypes attributes of function pointers), but only after you have obtained it by different means.

Solution 4:

The below approach worked for both Windows and Ubuntu. For Windows, Cygwin is required.

Suppose, there is a c file like below which name is test.c.

int func1(int a, int b){
    return a + b;
}

int func2(int a, int b){
    return a - b;
}

And the above c codes were compiled to test.dll file with the below commands:

gcc -shared -Wl,-soname,adder -o test.dll -fPIC test.c

And the below Python script finds which functions of the test.dll can be used by Python.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from subprocess import Popen, PIPE

out = Popen(
    args="nm ./test.dll", 
    shell=True, 
    stdout=PIPE
).communicate()[0].decode("utf-8")

attrs = [
    i.split(" ")[-1].replace("\r", "") 
    for i in out.split("\n") if " T " in i
]

from ctypes import CDLL

functions = [i for i in attrs if hasattr(CDLL("./test.dll"), i)]

print(functions)

The output I got in Windows is as below:

['func1', 'func2']

The output I got in Ubuntu is as below:

['_fini', 'func1', 'func2', '_init']

The items of the above list are objects of _FuncPtr class.