You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

64位Windows10下使用ctypes调用C编译DLL函数失败问题咨询

64位Windows10下C编译DLL用Python ctypes调用失败问题排查

我近期尝试将C代码编译为DLL后通过Python的ctypes加载调用,但始终未成功,运行环境为64位Windows10,原始C代码如下:

//Filename: my_functions.c
# include <stdio.h>
int square(int i){
    return i*i
}

我现将目前尝试过的两种方案总结如下:

方法1

首先我在命令提示符中使用cl.exe编译64位DLL,执行命令如下:

call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat" -arch=x64
cl.exe /D_USRDL /D_WINDLL my_functions.c /MT /link /DLL /OUT:my_functions.dll /MACHINE:X64

编译成功后得到my_functions.dll文件,随后我使用如下Python代码(Python 3.8,Spyder环境)尝试加载DLL:

# Filename: calling_c_functions.py
from ctypes import *
my_functions = CDLL("./my_functions.dll")
print(type(my_functions))
print(my_functions.square(10))
print("Done")

但运行后报错:AttributeError: function 'square' not found。
我查询微软官方文档了解到,DLL文件包含导出表,记录所有对外暴露的函数信息,这些函数需要通过ordinal number(序号)或name(名称)访问,导出名称可能和原函数名square不同。因此我尝试了第二种方案。

方法2

参考Stack Overflow相关问题《Python: accessing DLL function using ctypes -- access by function name fails》的解决方案,我修改C代码添加__declspec(dllexport)关键字,内容如下:

//Filename: my_functionsDLL2.dll
#include <stdio.h>
extern "C"
{
    __declspec(dllexport) int square(int i);
}
__declspec(dllexport) int square(int i)
{
   return i * i; 
}

编译得到DLL后,我尝试用link.exe查看DLL的导出函数名,执行命令如下:

call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\link.exe"
link /dump /exports my_functionsDLL2.dll

预期可以看到导出函数列表,但实际输出报LNK4048错误,提示文件格式无效被忽略,完整输出如下:

Microsoft (R) COFF/PE Dumper Version 14.29.30037.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file myfunctionsDLL2.dll
myfunctionsDLL2.dll : warning LNK4048: Invalid format file; ignored

  Summary

烦请各位帮忙排查我的操作存在什么问题,谢谢。


问题排查与解决方案

你操作里的错误集中在以下4个点:

  • 方法1的C代码没有添加函数导出声明,DLL导出表不会包含square函数,Python调用找不到属于正常现象,同时编译命令里的宏写错:/D_USRDL应为/D_USRDLL,少打了末尾的L。
  • 方法2的C代码混用了C语法:extern "C"是C独有语法,如果你的源文件后缀是.c,C编译器会直接报错,如果你后缀用了.cpp才会生效,同时你注释里把C源文件名写为.dll后缀属于笔误,编译时注意核对源文件名。
  • 查看导出表时报LNK4048是因为你调用了32位版本的link.exe:路径C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\下的是32位工具链,无法识别64位的PE文件格式,自然会报格式无效。
  • 原始C代码里return i*i末尾少了分号,属于语法错误,编译时会报错,你说编译成功大概率是手敲代码时漏写了。

正确操作步骤

  1. 修正C代码,如果用C语言编译(后缀.c),代码如下:
// 文件名:my_functions.c
#include <stdio.h>

__declspec(dllexport) int square(int i) {
    return i * i;
}

如果用C++编译(后缀.cpp),需要加extern "C"避免名称修饰:

// 文件名:my_functions.cpp
#include <stdio.h>

extern "C" __declspec(dllexport) int square(int i) {
    return i * i;
}
  1. 打开64位VS开发人员命令提示符,执行编译命令:
cl.exe /D_USRDLL /D_WINDLL my_functions.c /MT /link /DLL /OUT:my_functions.dll /MACHINE:X64
  1. 直接在当前命令提示符窗口执行导出表查看命令,不需要手动调用其他路径的link.exe,当前环境默认的64位工具链可以正常识别64位DLL:
link /dump /exports my_functions.dll

输出里可以看到导出的square函数名称。
4. Python调用前确认你的Python是64位版本,32位Python无法加载64位DLL,调用代码建议明确声明函数参数和返回值类型,避免隐式类型转换出错:

from ctypes import CDLL, c_int

my_functions = CDLL("./my_functions.dll")
# 声明参数类型为int
my_functions.square.argtypes = [c_int]
# 声明返回值类型为int
my_functions.square.restype = c_int

print(my_functions.square(10))
# 输出100即为调用成功

内容的提问来源于stack exchange,提问作者Ogiad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 14:06:05