Search code examples
pythoncdllctypescl

Using python CDLL to load dll, but no function from c code show up


I'm trying to import function written in c code into python. A minimal example I have tried is

//test.h
__declspec(dllexport)  int HW(int, int);
//test.c
#include <stdio.h>
#include <stdlib.h>
#include "test.h"

__declspec(dllexport) int HW(int a, int b)
{
    return a + b;
}

I also tried to remove the __declspec(dllexport) in either files. Then I did the following in Visual Studio 2019 CMD

cl /LD test.c

or

cl /LD test.c \libs\python37.lib

In python I did

from ctypes import *
a = CDLL('test.dll')

It turns out that HW is not an attribute of a. Which part did I do wrong?


Solution

  • The minimum code you need is the following. test.h isn't needed to export the function, and neither of the other includes were used.

    __declspec(dllexport) int HW(int a, int b)
    {
        return a + b;
    }
    

    Compile with cl /LD test.c (Microsoft). The python library isn't required. Make sure to use the 32-bit compiler if using 32-bit Python, or 64-bit compiler if using 64-bit Python.

    Demo of use:

    >>> from ctypes import *
    >>> a = CDLL('./test')
    >>> a.HW
    <_FuncPtr object at 0x000001E44AB7BA00>
    >>> a.HW(1,2)
    3
    

    Note you won't see the functions by inspection (i.e., dir(a)) until you access the function once:

    >>> from ctypes import *
    >>> a = CDLL('./test')
    >>> dir(a)
    ['_FuncPtr', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_func_flags_', '_func_restype_', '_handle', '_name']
    >>> a.HW
    <_FuncPtr object at 0x0000020A92B7B930>
    >>> dir(a)
    ['HW', '_FuncPtr', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_func_flags_', '_func_restype_', '_handle', '_name']