Python调用C++动态链接库(接口已用C封装)失败?

作者站长头像
站长
· 阅读数 8

(环境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个回答
avatar
test
2024-07-10

我碰到过类似问题, 可能是没有加载到c++的库文件python3.8更改了dll的搜索加载机制,即只在指定可行的位置搜索加载dll

比如我的 libstdc++-6.dll 在C:\MinGW\bin 下

就必须

os.add_dll_directory("C:\\MinGW\\bin")

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容