将静态库封装成python模块

很多硬件厂商的底层设备驱动都是以库的形式提供给开发者,有的是动态库,有的是静态库。开发上层应用,最快速便捷的方式当然还是用python,对于动态库,可以用python的ctypes库进行加载,而对于静态库,则要麻烦一些,今天折腾了很长时间,总算跑通了最简流程。

主要方法

静态库(LIB)是在编译链接阶段被静态地链接到程序中的,因此无法直接在 Python 中调用。Python 只能直接调用动态链接库(DLL)。

如果想在 Python 中使用静态库的功能,主要有以下几种方法:

  1. 将静态库转换为动态库:可以通过使用相应的编译器(例如,Visual Studio 或 GCC)将静态库转换为动态库(DLL)。这样就可以直接在 Python 中调用动态库了。

  2. 使用 C/C++ 扩展模块:可以使用 Python 的 C/C++ 扩展机制,将静态库中的函数封装为 C/C++ 扩展模块,然后在 Python 中调用这些模块。通过这种方式,可以直接在 Python 中使用静态库的功能。

  3. 使用第三方工具:有些第三方工具可以帮助将静态库转换为 Python 可用的动态库或 C/C++ 扩展模块。例如,Cython 可以将 C/C++ 代码转换为 Python 可执行的代码;SWIG 可以生成用于 Python 的 C/C++ 接口代码。

需要注意的是,将静态库转换为动态库或者创建 C/C++ 扩展模块都需要一定的 C/C++ 编程经验。如果你不熟悉 C/C++,可以考虑使用其他方法解决问题,如寻找已经有 Python 绑定的动态库或者使用其他库或工具实现相同的功能。

Cython

今天主要尝试了用Cython将静态库封装成python模块。

首先新建一个文件夹用作今天的操场:

# 以 lib_test 为例
mkdir lib_test && cd lib_test

lib_test目录下新建my_static_lib.hmy_static_lib.cpp两个文件,并分别写入以下内容:

// my_static_lib.h
#ifndef MY_STATIC_LIB_H
#define MY_STATIC_LIB_H#ifdef __cplusplus
extern "C" {
#endifvoid function1();
void function2();
void function3();
void function4();
void function5();
void function6();
void function7();
void function8();
void function9();
void function10();#ifdef __cplusplus
}
#endif#endif
// my_static_lib.cpp
#include <iostream>
#include "my_static_lib.h"void function1()
{std::cout << "This is function 1." << std::endl;
}void function2()
{std::cout << "This is function 2." << std::endl;
}void function3()
{std::cout << "This is function 3." << std::endl;
}void function4()
{std::cout << "This is function 4." << std::endl;
}void function5()
{std::cout << "This is function 5." << std::endl;
}void function6()
{std::cout << "This is function 6." << std::endl;
}void function7()
{std::cout << "This is function 7." << std::endl;
}void function8()
{std::cout << "This is function 8." << std::endl;
}void function9()
{std::cout << "This is function 9." << std::endl;
}void function10()
{std::cout << "This is function 10." << std::endl;
}

然后编写CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.0)
project(my_static_library)# 设置编译器为C++
set(CMAKE_CXX_STANDARD 11)# 添加静态库的源文件
add_library(my_static_lib STATICmy_static_lib.cpp
)

构建生成静态库:

# 新建 build 目录
mkdir build && cd build# 生成 vs 解决方案
cmake ..# 构建
cmake --build .

安装Cython

pip install cython

lib_test目录下新建my_static_lib.pyxsetup.py两个文件,并写入以下内容:

# my_static_lib.pyx
cdef extern from "my_static_lib.h":void function1()void function2()void function3()void function4()void function5()void function6()void function7()void function8()void function9()void function10()def py_function1():function1()def py_function2():function2()def py_function3():function3()def py_function4():function4()def py_function5():function5()def py_function6():function6()def py_function7():function7()def py_function8():function8()def py_function9():function9()def py_function10():function10()
# setup.py
from setuptools import Extension, setup
from Cython.Build import cythonizesetup(ext_modules=cythonize(Extension("my_static_lib", ["my_static_lib.pyx"], extra_link_args=["/LIBPATH:PATH\\to\\my_static_lib.lib"], libraries=["my_static_lib"]))
)

注意将示例中的PATH\\to\\my_static_lib.lib替换为实际的静态库所在绝对路径。

然后执行:

# 回到 lib_test 目录下
cd ..
python .\setup.py build_ext -i

测试一下:

❯ python
Python 3.8.10 (tags/v3.8.10:3d8993a, May  3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import my_static_lib
>>> my_static_lib.py_function()
Traceback (most recent call last):File "<stdin>", line 1, in <module>
AttributeError: module 'my_static_lib' has no attribute 'py_function'
>>> my_static_lib.py_function1()
This is function 1.
>>> my_static_lib.py_function5()
This is function 5.
>>> my_static_lib.py_function10()
This is function 10.

公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/31916.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode150道面试经典题--验证回文串(简单)

1.题目 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&#xff0c;如果它是 回文串 &#xff0c;返回 true &#xff1b;否…

uniapp 微信小程序 封装公共的请求js(api版本)

一、新建api文件夹 在项目目录下创建api文件夹&#xff0c;内放files跟index.js文件夹&#xff0c;files文件夹内放每个页面对应的js请求接口 1、index.js /*** api接口的统一出口*/ const api {}; const requireComponent require.context(./files, false, /\.js$/) requi…

SpringCloud实用篇2——Nacos配置管理 Feign远程调用 Gateway服务网关

目录 1 Nacos配置管理1.1 统一配置管理1.1.1 在nacos中添加配置文件1.1.2 从微服务拉取配置 1.2 配置热更新1.2.1 方式一1.2.2 方式二&#xff08;推荐&#xff09; 1.3.配置共享 2 搭建Nacos集群2.1 集群结构图2.2 搭建集群2.2.1 初始化数据库2.2.2 下载nacos2.2.3 配置Nacos2…

竞赛项目 深度学习的智能中文对话问答机器人

文章目录 0 简介1 项目架构2 项目的主要过程2.1 数据清洗、预处理2.2 分桶2.3 训练 3 项目的整体结构4 重要的API4.1 LSTM cells部分&#xff1a;4.2 损失函数&#xff1a;4.3 搭建seq2seq框架&#xff1a;4.4 测试部分&#xff1a;4.5 评价NLP测试效果&#xff1a;4.6 梯度截断…

面部表情识别4:C++实现表情识别(含源码,可实时检测)

面部表情识别4&#xff1a;C实现表情识别(含源码&#xff0c;可实时检测) 目录 面部表情识别4&#xff1a;C实现表情识别(含源码&#xff0c;可实时检测) 1.面部表情识别方法 2.人脸检测方法 3.面部表情识别模型(Python) &#xff08;1&#xff09; 面部表情识别模型的训练…

printf %.*s 原来是这样

今天看代码时&#xff0c;看到这样一个printf&#xff0c;以前没见过这样的&#xff0c;也没这样用过&#xff0c;一下子还真不知道是什么意思&#xff1a; // Response is received. Print it struct mg_http_message *hm (struct mg_http_message *) ev_data; printf("…

扫雷(超详解+全部码源)

C语言经典游戏扫雷 前言一.游戏规则二.所需文件三.创建菜单四.游戏核心内容实现1.创建棋盘2.打印棋盘3.布置雷4.排查雷5.game()函数具体实现 五.游戏运行实操六.全部码源 前言 &#x1f600;C语言实现扫雷是对基础代码能力的考察。通过本篇文章你将学会如何制作出扫雷&#xff…

Spring 使用注解储存对象

文章目录 前言存储 Bean 对象五大注解五大注解示例配置包扫描路径读取bean的示例 方法注解 Bean Bean 命名规则重命名 Bean 前言 通过在 spring-config 中添加bean的注册内容&#xff0c;我们已经可以实现基本的Spring读取和存储对象的操作了&#xff0c;但在操作中我们发现读…

每日一题——滑动窗口的最大值

滑动窗口的最大值 题目链接 暴力解法 最容易想到的当然还是通过两层循环来暴力求解&#xff1a;一层循环用来移动窗口&#xff0c;一层循环用来在窗口内找到最大值。这种做法的时间复杂度为O(kN)&#xff0c;会超出时间限制&#xff0c;因此&#xff0c;我们要找到更加高效的…

springboot国际化

springboot国际化 不需要引入额外的jar包 参考&#xff1a;https://zhuanlan.zhihu.com/p/551605839 1.rources要创建Resource Bundle 2.yml配置中引入Resource Bundle 引入Resource Bundle spring:messages:encoding: UTF-8basename: i18n/messages_common3.创建国际化工具…

彩色图转灰度图之c++实现(qt + 不调包)

1.介绍 在日常生活中&#xff0c;我们经常看到的图片是彩色图片&#xff0c;有时我们需要将彩色图片转换成灰度图片来处理&#xff0c;也就是将RGB三通道图片按照一定规则转换成一通道图片。 2.转换方式 彩色图片转灰度图片&#xff0c;一般有三种方法 第一种&#xff1a;平均法…

海思ss928部署手写数字识别模型

大致流程--------------------------------------------------------------------------------------------------------------------- 模型转换---------------------------------------------------------------------------------------------------- 1&#xff1a;准备MNI…

【EI复现】考虑区域多能源系统集群协同优化的联合需求侧响应模型(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

企业前后端分离软件架构如何设计?

企业前后端分离软件架构的设计涉及到前端和后端的独立性、通信方式、数据流管理等多个方面。下面我将为你介绍一个常见的前后端分离软件架构设计&#xff1a; 1、前端层&#xff1a; 框架选择&#xff1a;选择适合项目需求的前端框架&#xff0c;例如React、Vue.js、Angular等…

面试题记录

面试题记录 一.Vue中的合成事件和原生事件有哪些区别。二.parseint(3,2)返回什么值&#xff1f;为什么三.什么是闭包四.vue3和vue2区别有哪些五.vue3 响应式原理 双向绑定原理1. 响应式原理&#xff1a;2. 双向绑定原理&#xff1a;Vue3 中双向绑定的原理&#xff1a;下面是 Vu…

https的原理和方案

文章目录 https原理为什么要加密常见的加密方式对称加密非对称加密数据摘要&&数据指纹数据签名 https的几种工作方案方案一&#xff1a;只使用对称加密方案二&#xff1a;只使用非对称加密方案三&#xff1a;两端都使用非对称加密方案四&#xff1a;非对称加密 对称加…

苹果账号被禁用怎么办?

苹果账号被禁用怎么办&#xff1f; 转载&#xff1a;苹果账号被禁用怎么办&#xff1f; 当我们使用苹果手机登录App Store时&#xff0c;有时会遇到账号被禁用的提示。总结下来&#xff0c; 账号被禁用的原因可能有以下几种&#xff1a; 禁用的原因 1.在不同的设备上登录Ap…

CSS前端开发指南:创造精美的用户界面

简介&#xff1a; 《CSS前端开发指南&#xff1a;创造精美的用户界面》是一本旨在帮助读者掌握CSS技术&#xff0c;实现令人惊叹的前端用户界面的实用指南。无论您是初学者还是有经验的开发者&#xff0c;本书都将为您提供全面的知识和实用技巧&#xff0c;帮助您创建引人注目…

c语言每日一练(5)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…

什么是设计模式?

目录 概述: 什么是模式&#xff01;&#xff01; 为什么学习模式&#xff01;&#xff01; 模式和框架的比较&#xff1a; 设计模式研究的历史 关于pattern的历史 Gang of Four(GoF) 关于”Design”Pattern” 重提&#xff1a;指导模式设计的三个概念 1.重用(reuse)…