Python通过SWIG调用C++时出现的ImportError问题解析

2023-05-16

摘要 win10系统,编译器为mingw,按照教程封装C++的一个类并用python调用,一步步进行直到最后一步运行python代码时,在python代码中import example时报错ImportError: DLL load failed while importing _example: The specified module could not be found.本文记录我的解决方法和其它一些解决思路。

先测试C语言

官方文档有完整教程,命令分别为

  • swig -python example.i
  • gcc -c -fpic example.c example_wrap.c -I “C:/Users/xd15zhn/AppData/Local/Programs/Python/Python310/include”
  • gcc -shared example.o example_wrap.o -o _example.pyd -L “C:/Users/xd15zhn/AppData/Local/Programs/Python/Python310/libs” -lpython310

注意包含自己的头文件目录和库目录,gcc和g++的具体参数见文末的参考链接。
example.c

#include <stdio.h>
double My_variable = 3.0;
int my_sum(double a, double b) {
    return(a + b);
}
void my_print() {
    printf("Hello World!\n");
}

example.i

%module example
%{
    extern double My_variable;
    extern int my_sum(int n, int m);
    extern void my_print();
%}
extern double My_variable;
extern int my_sum(int n, int m);
extern void my_print();

main.py

import example
example.my_print()
print(example.my_sum(1,2))

再测试C++

  • swig -c++ -python example.i
  • g++ -c -fPIC example.cpp example_wrap.cxx -I “C:/Users/xd15zhn/AppData/Local/Programs/Python/Python310/include”
  • g++ -shared example.o example_wrap.o -o _example.pyd -L “C:/Users/xd15zhn/AppData/Local/Programs/Python/Python310/libs” -lpython310

example.cpp

#include <iostream>
#include "example.hpp"
void Example::say_hello() {
    std::cout << "Hello world!" << std::endl;
}
double Example::my_sum(double a, double b) {
    return a+b;
}

example.hpp

class Example {
public:
    void say_hello();
    double my_sum(double a, double b);
};

example.i

%module example
%{
#include "example.hpp"
%}
%include "example.hpp"

main.py

import example
e = example.Example()
e.say_hello()
print(e.my_sum(1,2))

运行本节开头的3条命令后,不出意外的话,运行3条命令后依次分别生成:

  1. example.py, example_wrap.cxx
  2. example.o example_wrap.o
  3. _example.pyd

问题描述与解决

最后运行main.py后在import example时报错ImportError: DLL load failed while importing _example: The specified module could not be found. stackoverflow上有人提到了这个问题,一个解决方法是

I met exactly the same problem after upgraded python to 3.9 on windows . After struggling for hours, I managed to solve it by manually copying some dlls from ***/mingw/bin/ where mingw32-g++ is found to where my ***.pyd is located. I’m sure that ***/mingw/bin/ has been appended to %PATH%, but don’t know why python3.9 couldn’t find it.

按照这个方法我把/mingw/bin/目录下的所有.dll文件全都复制到当前项目目录下确实解决了问题,但文中说只复制了一部分,想到使用静态编译需要用到两个命令-static-libstdc++-static-libgcc,然后测试了一下确实是只需要这两个文件。除了复制文件这一不太优雅的方法以外,只需要在python代码中加上/mingw/bin/目录即可,完整的python代码如下

import os
os.add_dll_directory('C:/Users/xd15zhn/Documents/mingw64/bin')
import example
e = example.Example()
e.say_hello()
print(e.my_sum(1,2))

但这种方法还是不够优雅,能不能把这两个动态库直接链接到_example.pyd文件里?我尝试在上面第3条命令后加上-llibgcc_s_sjlj-1 -llibstdc++-6,但没有用。不知道有没有更优雅的解决方法。

cmake

cmake_minimum_required(VERSION 3.14)
project(example)
set(CMAKE_BUILD_TYPE release)
list(APPEND CMAKE_PREFIX_PATH "C:/Users/xd15zhn/Documents/cpplibraries")
# set(MinGW_PATH "C:/Users/xd15zhn/Documents/mingw64/bin")
# set(CMAKE_SHARED_LINKER_FLAGS "-static-libgcc -static-libstdc++")
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
find_package(Python3 COMPONENTS NumPy REQUIRED)
find_package(SWIG REQUIRED)
message(STATUS "Python3_LIBRARIES: ${Python3_LIBRARIES}")
message(STATUS "Python3_INCLUDE_DIRS: ${Python3_INCLUDE_DIRS}")
message(STATUS "Python3_NumPy_INCLUDE_DIRS: ${Python3_NumPy_INCLUDE_DIRS}")

include(UseSWIG)
set(example_INTERFACE
    ${PROJECT_SOURCE_DIR}/cppsrc/example.i
)
set(example_SOURCES
    ${PROJECT_SOURCE_DIR}/cppsrc/example.cpp
)
set_source_files_properties(${example_INTERFACE} PROPERTIES CPLUSPLUS ON)
swig_add_library(example LANGUAGE python SOURCES ${example_INTERFACE} ${example_SOURCES})

target_include_directories(example PUBLIC
    ${PROJECT_SOURCE_DIR}/cppsrc
    ${Python3_INCLUDE_DIRS}
    ${Python3_NumPy_INCLUDE_DIRS}
)
target_link_libraries(example PUBLIC
    ${Python3_LIBRARIES}
)

其它

下面的代码用于单独生成example.cpp的动态库来测试自己写的代码是否有问题。

g++ example.cpp -fpic -shared -o example.dll
g++ main.cpp example.dll -o untitled

参考

SWIG doesn’t work on Windows with MinGW-w64 when binding C++ and Python: DLL load failed while importing: The specified module could not be found -stackoverflow
gcc静态编译之-static-libstdc++、-static-libgcc、-static -简书
g++编译详解 -CSDN博客
gcc&g++链接动态库或静态库方法 -CSDN博客
SWIG:Python调用C++(新手保姆级示范) -知乎
The specified module could not be found的解决办法 -CSDN博客

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python通过SWIG调用C++时出现的ImportError问题解析 的相关文章

  • 在PyGI中获取窗口句柄

    在我的程序中 我使用 PyGObject PyGI 和 GStreamer 在 GUI 中显示视频 该视频显示在Gtk DrawingArea因此我需要获取它的窗口句柄realize 信号处理程序 在 Linux 上 我使用以下方法获取该句
  • LibreOffice 并行将 .docx 转换为 .pdf 效果不佳

    我有很多 docx 文件需要转换为 pdf 将它们一一转换需要很长时间 所以我编写了一个 python 脚本来并行转换它们 from subprocess import Popen import time import os os chdi
  • McNemar 在 Python 中的测试以及分类机器学习模型的比较 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有用 Python 实现的好的 McNemar 测试 我在 Scipy stats 或 Scikit
  • Python re无限执行

    我正在尝试执行这段代码 import re pattern r w w s re compiled re compile pattern results re compiled search COPRO HORIZON 2000 HOR p
  • 指示电子邮件的类型

    我有以下自动化程序 它将电子邮件发送给我自己 并添加了特定的链接 import win32com client as win32 import easygui import tkinter as to from tkinter import
  • 使用 Python 3 动态插入到 sqlite

    我想使用 sqlite 写入多个表 但我不想提前手动指定查询 有数十种可能的排列 例如 def insert sqlite tablename data list global dbc dbc execute insert into tab
  • 检查 python 中命令行参数的数量

    我是蟒蛇新手 还是把脚弄湿了 我正在尝试做这样的事情 import sys if len sys argv lt 3 or lt len sys argv gt 3 print This script will compare two fi
  • 为什么第二个 request.session cookies 返回空?

    我想使用 requests Session post 登录网站 但是当我已经登录主页 然后进入帐户页面时 看来cookies还没有保存 因为cookies是空的 而且我无法进入正确的帐户页面 import requests from bs4
  • 使用 Pytest 的参数化添加测试功能的描述

    当其中一个测试失败时 可以在测试正在测试的内容的参数化中添加描述 快速了解测试失败的原因 有时您不知道测试失败的原因 您必须查看代码 通过每个测试的描述 您就可以知道 例如 pytest mark parametrize num1 num2
  • 是否有一个包可以维护所有带有符号的货币列表?

    是否有一个 python 包提供所有 或相当完整 货币的列表与符号 如美元的 有优秀的pycountry 贪财的 https github com limist py moneyed and ccy http code google com
  • 如何将 sql 数据输出到 QCalendarWidget

    我希望能够在日历小部件上突出显示 SQL 数据库中的一天 就像启动程序时突出显示当前日期一样 在我的示例中 它是红色突出显示 我想要发生的是 当用户按下突出显示的日期时 数据库中日期旁边的文本将显示在日历下方的标签上 这是我使用 QT De
  • 在 Mac OSX 上从 Python 3.6 运行 wine 命令

    我正在尝试用 Python 编写一个打开的脚本wine然后发送代码到wine终端打开一个 exe程序 这 exe程序也是命令驱动的 我可以打开wine 但我无法进一步 import shlex subprocess line usr bin
  • 更改QLineEdit的ClearButton图标

    我想在Windows 10 1909 64位 上的Python 3 8和PyQt5 5 15 0 上更改我的QLineEdit的ClearButton图标 稍后我想在Linux上运行代码 我尝试应用此处找到的代码 如何在 QLineEdit
  • 时间序列数据预处理 - numpy strides 技巧以节省内存

    我正在预处理一个时间序列数据集 将其形状从二维 数据点 特征 更改为三维 数据点 时间窗口 特征 在这样的视角中 时间窗口 有时也称为回顾 指示作为输入变量来预测下一个时间段的先前时间步长 数据点的数量 换句话说 时间窗口是机器学习算法在对
  • Python 2 的 `exceptions` 模块在 Python3 中丢失了,它的内容到哪里去了?

    一位朋友提到 对于 Python 2 假设您在命令行上的路径环境变量中有它 pydoc exceptions 非常有用 知道它应该可以为他每周节省几分钟的网络查找时间 我自己每周都会用谷歌搜索一次例外层次结构 所以这对我来说也是一个有用的提
  • 为什么这个 if 语句会导致语法错误

    我正在尝试设置一个 elif 语句 如果用户按下 Enter 键 代码将继续 但是我不断遇到语法错误 GTIN 0 while True try GTIN int input input your gtin 8 number if len
  • 在 numpy 中连接维度

    我有x 1 2 3 4 5 6 7 8 9 10 11 12 shape 2 2 3 I want 1 2 3 4 5 6 7 8 9 10 11 12 shape 2 6 也就是说 我想连接中间维度的所有项目 在这种特殊情况下我可以得到这
  • Python 中的 Unix cat 函数 (cat * > merged.txt)? [复制]

    这个问题在这里已经有答案了 一旦建立了目录 有没有办法在Python中使用Unix中的cat函数或类似的函数 我想将 files 1 3 合并到 merged txt 我通常会在 Unix 中找到该目录 然后运行 cat gt merged
  • 如何通过点击复制 folium 地图上的标记位置?

    I am able to print the location of a given marker on the map using folium plugins MousePosition class GeoMap def update
  • 使用 paramiko 运行 Sudo 命令

    我正在尝试执行sudo使用 python paramiko 在远程计算机上运行命令 我尝试了这段代码 import paramiko ssh paramiko SSHClient ssh set missing host key polic

随机推荐

  • matlab中值滤波实现

    中值滤波是一种典型的非线性滤波 xff0c 是基于排序统计理论的一种能够有效抑制噪声的非线性信号处理技术 xff0c 基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值 xff0c 让周围的像素值接近真实的值从而消除孤立的噪声点 该方
  • 程序员的情人节

    今天是一个好的节日 xff0c 七夕呀 xff01 程序是最好的女朋友 xff0c 它是不会骗你的 它偶尔会发些小的情绪 只是你没有懂它
  • stm32-Hardfault及内存溢出的查找方法

    STM32内存结构 1 要点 1 1 两种存储类型 RAM 和 Flash RAM可读可写 xff0c 在STM32的内存结构上 xff0c RAM地址段分布 0x2000 0000 0x2000 0000 43 RAM size Flas
  • raylib部分源代码功能解读

    官网 https www raylib com https github com raysan5 raylib 我根据自己的需求裁剪了多余功能后的代码 xff1a https gitee com xd15zhn raylib https g
  • 无量纲处理、量纲变换与实时仿真理论

    基本原理 万有引力公式 d 2 r
  • 局域网windows平台下时间同步

    最近单位出现很多应为系统时间不统一造成的问题 xff0c 如 客户机时间与服务器时间不同步 xff0c 而客户机使用软件是读取本机时间上传服务器 xff0c 这样就会造成排序错误 每次开机修改很繁琐 我就想到了在局域网内假设时间服务器的想法
  • 水下潜航器的建模与控制

    线性系统理论大作业 待完成 题目 水下潜器模型 xff0c 可能是潜艇或者鱼雷等对象 一个主推进螺旋桨 xff0c 前后两对水平陀翼 xff0c 后面一对垂直陀翼 潜器前进过程中 xff0c 通过调节助推进螺旋桨推力 xff0c 以及三对陀
  • 演化博弈、复制动态方程与仿真

    本文只整理和总结一下我的理解 xff0c 文末列出了可供参考的更详细完整的资料 建议先看参考资料 1 xff08 博弈论公开课 xff09 的博弈论课程 xff0c 可以直接从第11讲开始看 参考链接 2 是关于演化博弈非常经典的一本书 参
  • 演化博弈方法用于多智能体系统最优资源分配

    演化博弈方法用于多智能体系统最优资源分配 Evolutionary game theoretic approach for optimal resource allocation in multi agent systems 论文复现见 论
  • [论文复现]演化博弈方法用于多智能体系统最优资源分配

    原文 演化博弈方法用于多智能体系统最优资源分配 CSDN博客 https ieeexplore ieee org document 8243778 问题描述 有2种资源分配给6个个体 xff0c 2种资源的总量分别为 y 1 61 545
  • 基于博弈学习的分布式卫星任务规划

    基于博弈学习的分布式卫星任务规划 Distributed Satellite Mission Planning via Learning in Games 摘要 对地观测卫星群的任务规划是一个复杂的问题 xff0c 它提出了重大的理论和技术
  • 多星分布式任务分配中的博弈自组织

    多星分布式任务分配中的博弈自组织 Game theoretic self organization in multi satellite distributed task allocation 论文复现见 论文复现 多星分布式任务分配中的博
  • 自用的矩阵运算库zhnmat使用说明

    自用的矩阵运算库zhnmat使用说明 包含两个主要类 xff1a Mat和Vector3d xff0c 可以用于一些简单的矩阵和三维向量场景 xff0c 代码较简单 xff0c 没有任何性能优化 xff0c 可用于学习参考 代码仓库 htt
  • 非线性系统的反馈线性化

    仿射非线性或非仿射非线性指对输入是否是线性的 例如 xff0c 系统能够写成 x 61 f x
  • 基于特征模型的全系数自适应控制

    摘要 xff1a 首先推导了全系数和等于1的证明过程 xff0c 分析了等效时间常数的概念 xff0c 然后推导了递推最小二乘公式并用于参数辨识的方法 xff0c 最后给几个仿真的例子 全系数之和等于1 被控对象用微分方程 y n
  • raylib一些示例代码

    摘要 xff1a 几种相机视角 3D预览图视角 xff1a 鼠标拖动 xff0c 滚轮缩放 只能沿着中心点 第一视角 xff1a WSAD分别控制视角的前后左右移动 xff0c EQ分别控制上下移动 xff0c 滚轮控制移动速度 画正方体线
  • gnome session 中的开机启动程序配置文件

    我找了很久才找到的 xff1a 管理员状态下 xff1a linux Blue home library config autostart ls gnome terminal desktop stardict desktop 我开机启动的两
  • 使用深度Q网络(Deep Q Network)学习控制倒立摆

    使用深度Q网络 Deep Q Network 学习控制单摆 原文 xff1a https qiita com ashitani items bb393e24c20e83e54577 摘要 xff1a 我们将尝试使用Deep Q网络 xff0
  • python多次调用exe文件运行不同的结果

    摘要 xff1a 有个C 43 43 项目是读取配置参数文件并打印对应的结果 xff0c 后来需要多次修改配置文件并运行 xff0c 于是想到写个python脚本执行这一过程 写一个测试项目 xff0c 项目结构如下 xff1a 根目录 m
  • Python通过SWIG调用C++时出现的ImportError问题解析

    摘要 win10系统 xff0c 编译器为mingw xff0c 按照教程封装C 43 43 的一个类并用python调用 xff0c 一步步进行直到最后一步运行python代码时 xff0c 在python代码中import exampl