pythoncdllctypes

loading dll and calling function gives error in python


i am trying to use a dll in ctypes but it gives me errors

i am trying to make a python app that uses a dll for the case of 'hotreloading' and i keep getting errors

so i set up a test thinking it was the folder that is stored in

Commands i used: gcc is broken for me on Windows

g++ -c .\clib.c -o .\clib.o
g++ -shared .\clib.o -fPIC -o .\clib.dll
py .\main.py

clib.h

#define Export __declspec(dllexport)

Export void display(void);

clib.c

#include <stdio.h>

#include "clib.h"

Export void display(void)
{
    printf("Hello, World!\n");
}

main.py

from ctypes import CDLL
from os import getcwd

CDLL(f"{getcwd()}/clib.dll").display()

the error i get

Traceback (most recent call last):
  File "<dev-folder>\main.py", line 4, in <module>
    CDLL(f"{getcwd()}/clib.dll").display()
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\<current-user>\AppData\Local\Programs\Python\Python313\Lib\ctypes\__init__.py", line 403, in __getattr__
    func = self.__getitem__(name)
  File "C:\Users\<current-user>\AppData\Local\Programs\Python\Python313\Lib\ctypes\__init__.py", line 408, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'display' not found

idk if i am doing something wrong, but please help me understand what i must do

this is what happens when i use gcc that's why i am using g++:

gcc -c .\clib.c
Usage: cpp [switches] input output
Switches:
  -include <file>           Include the contents of <file> before other files
  -imacros <file>           Accept definition of marcos in <file>
  -iprefix <path>           Specify <path> as a prefix for next two options
  -iwithprefix <dir>        Add <dir> to the end of the system include paths
  -iwithprefixbefore <dir>  Add <dir> to the end of the main include paths
  -isystem <dir>            Add <dir> to the start of the system include paths
  -idirafter <dir>          Add <dir> to the end of the system include paths
  -I <dir>                  Add <dir> to the end of the main include paths
  -nostdinc                 Do not search the system include directories
  -nostdinc++               Do not search the system include directories for C++
  -o <file>                 Put output into <file>
  -pedantic                 Issue all warnings demanded by strict ANSI C
  -traditional              Follow K&R pre-processor behaviour
  -trigraphs                Support ANSI C trigraphs
  -lang-c                   Assume that the input sources are in C
  -lang-c89                 Assume that the input is C89; depricated
  -lang-c++                 Assume that the input sources are in C++
  -lang-objc                Assume that the input sources are in ObjectiveC
  -lang-objc++              Assume that the input sources are in ObjectiveC++
  -lang-asm                 Assume that the input sources are in assembler
  -lang-chill               Assume that the input sources are in Chill
  -std=<std name>           Specify the conformance standard; one of:
                            gnu89, gnu9x, c89, c9x, iso9899:1990,
                            iso9899:199409, iso9899:199x
  -+                        Allow parsing of C++ style features
  -w                        Inhibit warning messages
  -Wtrigraphs               Warn if trigraphs are encountered
  -Wno-trigraphs            Do not warn about trigraphs
  -Wcomment{s}              Warn if one comment starts inside another
  -Wno-comment{s}           Do not warn about comments
  -Wtraditional             Warn if a macro argument is/would be turned into
                             a string if -traditional is specified
  -Wno-traditional          Do not warn about stringification
  -Wundef                   Warn if an undefined macro is used by #if
  -Wno-undef                Do not warn about testing undefined macros
  -Wimport                  Warn about the use of the #import directive
  -Wno-import               Do not warn about the use of #import
  -Werror                   Treat all warnings as errors
  -Wno-error                Do not treat warnings as errors
  -Wall                     Enable all preprocessor warnings
  -M                        Generate make dependencies
  -MM                       As -M, but ignore system header files
  -MD                       As -M, but put output in a .d file
  -MMD                      As -MD, but ignore system header files
  -MG                       Treat missing header file as generated files
  -g                        Include #define and #undef directives in the output
  -D<macro>                 Define a <macro> with string '1' as its value
  -D<macro>=<val>           Define a <macro> with <val> as its value
  -A<question> (<answer>)   Assert the <answer> to <question>
  -U<macro>                 Undefine <macro>
  -u or -undef              Do not predefine any macros
  -v                        Display the version number
  -H                        Print the name of header files as they are used
  -C                        Do not discard comments
  -dM                       Display a list of macro definitions active at end
  -dD                       Preserve macro definitions in output
  -dN                       As -dD except that only the names are preserved
  -dI                       Include #include directives in the output
  -ifoutput                 Describe skipped code blocks in output
  -P                        Do not generate #line directives
  -$                        Do not include '$' in identifiers
  -remap                    Remap file names when including files.
  -h or --help              Display this information
cpp: Too many arguments

Solution

  • We can see the name is mangled so you need to use extern "C"

    objdump show the name is mangled

    or just use gcc to compile