python - 从 Python 编译的 C DLL 调用简单的 "Hello World!"函数会导致 OSError : exception: access violation

标签 python c windows dll linker

C 代码:

// 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;
}

构建脚本:

# 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")

主要脚本:

# 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()

运行python build.py后,DLL的创建没有任何问题。但是,当运行 python main.py 时,“add_numbers”函数可以工作,但调用“hello”函数会导致“OSError:异常:访问冲突写入 0x0000000000002C44”。

我错过了什么吗?我是否需要以某种方式告诉编译器包含“stdio.h” header ?

最佳答案

似乎 distutils 错误地链接了 msvc CRT。

您不应导入带有下划线的任何内容,例如 _distutils,因为它不是公共(public) API 的一部分,您不应使用它。

由于这是一个简单的 Windows dll,您可以直接调用 cl.exe 并编译它。 (请确保在执行此操作之前打开 x64 Native Tools Command Prompt for VS 2022 命令提示符)

cl.exe /LD my_module.c

这可以工作,但如果您有更多文件,那么您可能应该为其创建一个 cmake 项目并使用它从 python 构建 C dll。

快速浏览一下 dependenciesdistutils 生成的一个。

enter image description here

与直接来自 cl.exe 的相比。

enter image description here

将所有额外的依赖项从 Windows sdk 复制到 dll 文件夹应该可以使其正常工作,但这不是正确的方法。

关于python - 从 Python 编译的 C DLL 调用简单的 "Hello World!"函数会导致 OSError : exception: access violation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77502055/

相关文章:

windows - 是否可以在运行时设置 Windows 程序的语言或区域设置?

python - 计算每天发生的观察次数

arrays - C:定义具有 64 位对齐起始地址的数组的可移植方法?

c++ - SwitchDesktop 暂时工作,但片刻后切换回来

C - 尝试发送()数据但有错误

c - 取消引用指向结构的指针 - 使间接操作数无效?

windows - telnet 输出使用 .bat 文件将其保存到文件

python - Flask jsonify 返回奇怪的数组?

python - 将 Blender2.79 代码转换为 Blender2.8 : game sensors

Python 列表与非唯一项的交集