Python调用C++动态链接库(接口已用C封装)失败?
(环境Win11,Python3.9.8,g++和gcc8.1.0都是64位,clang++ 17.0.0也是64位。)经测试,C程序能正常调用,而用extern "C"封装过的C++程序任然无法正常调用。
C:
PS D:\data_CppWorks\Project3_pythoncpp> cat .\cdll.c
#include <stdio.h>
void my_add(int num){
long int result = 0;
long int i = 1;
for(i=1; i<=num; i++){
result += i;
}
printf("C result : %ld",result);
}
编译:gcc -o cdll.so -shared -fPIC .\cdll.c
python调用:
PS D:\data_CppWorks\Project3_pythoncpp> cat .\add.py
# -*- coding:utf-8 -*-
import ctypes
import os
os.add_dll_directory("D:\\data_CppWorks\\Project3_pythoncpp")
def main():
num = int(input("Enter an Integer # "))
result = 0
result = ctypes.cdll.LoadLibrary("D:\\data_CppWorks\\Project3_pythoncpp\\cdll.so")
result.my_add(num) # 调用C中的my_add函数
p_result = sum(range(num+1))
print('\n' + '-'*20)
print('Results counted from 1 to {} = {}'.format(num,p_result))
if __name__ == "__main__":
main()
输出:
PS D:\data_CppWorks\Project3_pythoncpp> python .\add.py
Enter an Integer # 6
C result : 21
--------------------
Results counted from 1 to 6 = 21
因为我正常不用C,用C++测试时发现问题:
PS D:\data_CppWorks\Project3_pythoncpp> cat .\cppdll.cpp
#include <iostream>
using namespace std;
void my_add(int num) {
long int result = 0;
long int i = 1;
for (i = 1; i <= num; i++) {
result += i;
}
cout << "CPP result" << result << endl;
}
extern "C" {
int num;
void my_add_c(int num) {
my_add(num);
}
}
g++编译:g++ -o cppdll.so -shared -fPIC .\cppdll.cpp
python调用:
# -*- coding:utf-8 -*-
import ctypes
import os
os.add_dll_directory("D:\\data_CppWorks\\Project3_pythoncpp")
def main():
num = int(input("Enter an Integer # "))
result = 0
result = ctypes.cdll.LoadLibrary("D:\\data_CppWorks\\Project3_pythoncpp\\cppdll.so")
result.my_add_c(num) # 调用extern "C"部分的函数
p_result = sum(range(num+1))
print('\n' + '-'*20)
print('Results counted from 1 to {} = {}'.format(num,p_result))
if __name__ == "__main__":
main()
输出:
PS D:\data_CppWorks\Project3_pythoncpp> python .\add.py
Enter an Integer # 6
Traceback (most recent call last):
File "D:\data_CppWorks\Project3_pythoncpp\add.py", line 15, in <module>
main()
File "D:\data_CppWorks\Project3_pythoncpp\add.py", line 8, in main
result = ctypes.cdll.LoadLibrary("D:\\data_CppWorks\\Project3_pythoncpp\\cppdll.so")
File "D:\Users\py3.9.8\lib\ctypes\__init__.py", line 452, in LoadLibrary
return self._dlltype(name)
File "D:\Users\py3.9.8\lib\ctypes\__init__.py", line 374, in __init__
self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'D:\data_CppWorks\Project3_pythoncpp\cppdll.so' (or one of its dependencies). Try using the full path with constructor syntax.
这里测试过调用result.my_add_c(num)和result.my_add(num),以及g++打包为so和dll,还有更换绝对路径、相对路径,用clang++编译,都是同样的报错,推断是缺少依赖包,但是按照别人博客里的说法,用过extern "C"就可以正常输出了,不知道我的是怎么回事?
回复
1个回答
test
2024-07-10
我碰到过类似问题, 可能是没有加载到c++的库文件python3.8更改了dll的搜索加载机制,即只在指定可行的位置搜索加载dll
比如我的 libstdc++-6.dll 在C:\MinGW\bin 下
就必须
os.add_dll_directory("C:\\MinGW\\bin")
回复
适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容