The C code:
// my_module.c
#include <stdio.h>
__declspec(dllexport)
void hello() {
printf("Hello World!\n");
}
__declspec(dllexport)
int add_numbers(int a, int b) {
return a + b;
}
// entry point
int main() {
return 0;
}
The build script:
# build.py
from setuptools._distutils.ccompiler import new_compiler
compiler = new_compiler()
compiler.compile(["my_module.c"])
compiler.link_shared_lib(["my_module.obj"], "my_module")
The main script:
# main.py
import ctypes
my_module = ctypes.CDLL("./my_module.dll")
my_module.add_numbers.argtypes = ctypes.c_int, ctypes.c_int
my_module.add_numbers.restype = ctypes.c_int
my_module.hello.argtypes = ()
my_module.hello.restype = None
result = my_module.add_numbers(3, 4)
print(type(result), result)
my_module.hello()
After running python build.py
, the dll is created without issues. However, when running python main.py
, the "add_numbers" function works, but calling the "hello" function results in "OSError: exception: access violation writing 0x0000000000002C44".
Am I missing something? Do I somehow need to tell the compiler to include the "stdio.h" header?
it seems distutils
is linking the msvc CRT incorrectly.
you shouldn't import anything with an underscore such as _distutils
, as it is not a part of the public API and you shouldn't use it.
since this is a simple windows dll you could call cl.exe
directly and compile it. (make sure you open x64 Native Tools Command Prompt for VS 2022
command prompt before you do)
cl.exe /LD my_module.c
which will work, but if you have more files then you should probably create a cmake
project for it and use it to build your C dll from python.
a quick look at the dependencies of the one generated from distutils
.
vs the one from just cl.exe
directly.
copying all extra dependencies from the windows sdk to the dll folder should get it to work, but this is not the correct approach.