[Python] 如何通过ctypes库来调用C++ 动态库 DLL?

这篇具有很好参考价值的文章主要介绍了[Python] 如何通过ctypes库来调用C++ 动态库 DLL?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ctypes库介绍

ctypes是Python的一个外部库,它提供了一种灵活的方式来调用C语言的动态链接库(DLL)或共享库(SO)。通过ctypes,我们可以在Python中直接调用C语言编写的函数和变量,从而实现跨语言的互操作。

ctypes 它提供了与 C 兼容的数据类型,并允许调用 DLL 或共享库中的函数。可使用该模块以纯 Python 形式对这些库进行封装。

ctypes提供的方法和C语言对应的数据类型如下表:

[Python] 如何通过ctypes库来调用C++ 动态库 DLL?,python,C++,c++,python

ctypes --- Python 的外部函数库 — Python 3.12.1 文档

ctypes — A foreign function library for Python — Python 3.12.1 documentation

默认情况下都会假定函数返回 C int 类型。 其他返回类型可通过设置函数对象的 restype 属性来指定。

[Python] 如何通过ctypes库来调用C++ 动态库 DLL?,python,C++,c++,python

使用ctypes的基本步骤如下:

  1. 导入ctypes库
  2. 加载动态链接库或共享库
  3. 定义函数原型
  4. 调用函数

创建C++ 动态库

如何通过VS 2022创建C++动态连接库,可以阅读:[C++] VS 2022演练 - 创建和使用用动态连接库(DLL) (详细图文)-CSDN博客

这里是我创建好的MathLibrary动态链接库:

[Python] 如何通过ctypes库来调用C++ 动态库 DLL?,python,C++,c++,python

 MathLibrary.h

// MathLibrary.h - Contains declarations of math functions
#pragma once

#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif

// The Fibonacci recurrence relation describes a sequence F
// where F(n) is { n = 0, a
//               { n = 1, b
//               { n > 1, F(n-2) + F(n-1)
// for some initial integral values a and b.
// If the sequence is initialized F(0) = 1, F(1) = 1,
// then this relation produces the well-known Fibonacci
// sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

// Initialize a Fibonacci relation sequence
// such that F(0) = a, F(1) = b.
// This function must be called before any other function.
extern "C" MATHLIBRARY_API void fibonacci_init(
    const unsigned long long a, const unsigned long long b);

// Produce the next value in the sequence.
// Returns true on success and updates current value and index;
// false on overflow, leaves current value and index unchanged.
extern "C" MATHLIBRARY_API bool fibonacci_next();

// Get the current value in the sequence.
extern "C" MATHLIBRARY_API unsigned long long fibonacci_current();

// Get the position of the current value in the sequence.
extern "C" MATHLIBRARY_API unsigned fibonacci_index();

备注: 代码中在MATHLIBRARY_API前面必须增加 “ extern "C" ” 前缀,否则会导致ctypes无法找到对应的函数,如下图所示:

[Python] 如何通过ctypes库来调用C++ 动态库 DLL?,python,C++,c++,python

在C++中,extern "C"是一个链接指示符,用于告诉编译器按照C语言的方式进行编译。这意味着在C++代码中使用extern "C"声明的函数或变量将被当作C语言的函数或变量进行处理,而不会被当作C++的函数或变量进行处理。

extern "C"的作用主要有以下几点:

  1. 保持函数名和变量名的C语言兼容性。在C++中,函数名和变量名默认会添加前缀“_”,而在C语言中则不会。使用extern "C"可以避免这种情况的发生。

  2. 保持函数参数类型的C语言兼容性。在C++中,函数参数类型可能会被自动推导为模板类型,而在C语言中则不会。使用extern "C"可以避免这种情况的发生。

  3. 保持函数调用约定的C语言兼容性。在C++中,函数调用约定可能会有所不同,如stdcall、cdecl等,而在C语言中则只有一种调用约定。使用extern "C"可以避免这种情况的发生。

  4. 与某些C语言库进行交互。有些C语言库可能不支持C++的名称修饰(name mangling),这时可以使用extern "C"来避免名称修饰带来的问题。

MathLibrary.cpp

// MathLibrary.cpp : Defines the exported functions for the DLL.
#include <utility>
#include <limits.h>
#include "MathLibrary.h"

// DLL internal state variables:
static unsigned long long previous_;  // Previous value, if any
static unsigned long long current_;   // Current sequence value
static unsigned index_;               // Current seq. position

// Initialize a Fibonacci relation sequence
// such that F(0) = a, F(1) = b.
// This function must be called before any other function.
void fibonacci_init(
    const unsigned long long a,
    const unsigned long long b)
{
    index_ = 0;
    current_ = a;
    previous_ = b; // see special case when initialized
}

// Produce the next value in the sequence.
// Returns true on success, false on overflow.
bool fibonacci_next()
{
    // check to see if we'd overflow result or position
    if ((INT_MAX - previous_ < current_) ||
        (20 == index_))
    {
        return false;
    }

    // Special case when index == 0, just return b value
    if (index_ > 0)
    {
        // otherwise, calculate next sequence value
        previous_ += current_;
    }
    std::swap(current_, previous_);
    ++index_;
    return true;
}

// Get the current value in the sequence.
unsigned long long fibonacci_current()
{
    return current_;
}

// Get the current index position in the sequence.
unsigned fibonacci_index()
{
    return index_;
}

构建生成MathLibrary.dll:

[Python] 如何通过ctypes库来调用C++ 动态库 DLL?,python,C++,c++,python

python调用C++动态链接库

[Python] Jupyter Notebook(Jupyter Lab)介绍,安装,配置,启动及创建第一个notebook_python 启动jupyter lab-CSDN博客

1)把MathLibarary.dll上传到Jupyter Notebook所在的目录。

2)在Jupyter Notebook中运行下面的Python代码片段。

import ctypes
from ctypes import c_bool
math_dll = ctypes.cdll.LoadLibrary('./MathLibrary.dll')
# Initialize a Fibonacci relation sequence.
math_dll.fibonacci_init(1, 1)

math_dll.fibonacci_next.restype = c_bool

# Write out the sequence values until overflow.
while True:
    print(math_dll.fibonacci_index(), ": ", math_dll.fibonacci_current())
    if not math_dll.fibonacci_next():
        break
# Report count of values written before overflow.
print(math_dll.fibonacci_index() + 1, " Fibonacci sequence values fit in an unsigned 64-bit integer.");

备注:ctypes默认情况下都会假定函数返回 C int 类型。 其他返回类型可通过设置函数对象的 restype 属性来指定,因为fibonacci_next函数返回的是bool值,所以这里需要自己来规定fibonacci_next的返回类型为c_bool,否则会导致fibonacci_next返回的是int,无法进行到break语句。

[Python] 如何通过ctypes库来调用C++ 动态库 DLL?,python,C++,c++,python

[Python] 如何通过ctypes库来调用C++ 动态库 DLL?,python,C++,c++,python

当然,你也可以直接把上面的代码保存为.py文件,然后放在MathLibrary.dll相同的目录下,直接通过python运行.py文件。文章来源地址https://www.toymoban.com/news/detail-805746.html

到了这里,关于[Python] 如何通过ctypes库来调用C++ 动态库 DLL?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C#调用C++封装的SDK库(dll动态库)——下

    一、说明 上一篇我们相当于封装的是C语言风格的动态dll库,供C#来调用的。 C#调用C++封装的SDK库(dll动态库)——上 如果我们要封装的是下面的类呢?我们该怎么办?大家先思考下。  二、思路 不知道大家还记得设计模式中的单例模式吗? 我们可以采用类似的处理方式,通过

    2023年04月25日
    浏览(33)
  • Python调用动态链接库(DLL)

    Python调用动态链接库(DLL) 动态链接库(Dynamic Link Libraries,简称DLL)是一种被多个程序共享的库文件,可以被用于将程序分解为小模块,减少内存占用,加快程序运行速度。而Python作为一种高级编程语言,可以方便地调用外部的DLL文件。 在Python中,可以使用ctypes模块来调用

    2024年02月13日
    浏览(37)
  • 对《VB.NET通过VB6 ActiveX DLL调用PowerBasic及FreeBasic动态库》的改进

    《VB.NET通过VB6 ActiveX DLL调用PowerBasic及FreeBasic动态库》使用的Activex DLL公共对象是需要先注册的。https://blog.csdn.net/weixin_45707491/article/details/132437502?spm=1001.2014.3001.5501 Activex DLL事前注册,一次多用说起来也不是啥大问题,但不能更改到其它文件夹,否则程序找不到会出错,改地方

    2024年02月11日
    浏览(66)
  • VS2022环境下C++ DLL动态链接库的编写和调用

    1、新建动态链接库项目 2、新建类 3、宏定义 4、使用宏定义修饰类 调用DLL动态链接库大致有两种方法: 一种是“隐式调用”,需要.h头文件、.lib符号文件、.dll动态库文件; 一种是“显示调用”,需要.dll动态库文件; 此处介绍第一种调用方式。 1、创建项目 2、项目属性

    2024年02月14日
    浏览(36)
  • Go语言中,如何调用C++的dll文件

    我将给出一个完整的示例来说明如何调用C++ DLL文件。首先,我们将创建一个简单的C++ DLL,然后编写Go代码来调用该DLL。 创建C++ DLL文件( example.cpp ): 编译C++代码为DLL文件: 使用MinGW编译器编译 example.cpp 文件,生成 example.dll 文件。 -Wl,–out-implib,libexample.a -Wl,–output-def,exa

    2024年03月12日
    浏览(97)
  • python通过pyautogui库来控制鼠标和键盘

    PyAutoGUI是一个纯Python的GUI自动化工具,通过它可以用程序自动控制鼠标和键盘操作。它支持Windows, MacOS和Linux。 安装: 基本用法看代码,非常简单易用。 运行脚本的时候,MacOS会提示你打开系统偏好控制,要求允许运行脚本的程序控制电脑,允许即可。 先看一下屏幕坐标系:

    2024年02月09日
    浏览(38)
  • python通过ctypes传参numpy给c语言函数

    gcc -o demo.so -std=c++11 -shared -fPIC demo.c  python3 main.py 概述: 示例实现了numpy数组加上100并通过另外的数组的指针获取返回值。主要过程是 numpy数组转换成c_void_p类型,然后传参给c语言函数,c语言函数中指针强转到需要的数据类型,然后再处理。这样即可改变numpy数组中的数值实

    2024年02月12日
    浏览(28)
  • Python如何调用DLL库?——实例详解及代码

    Python如何调用DLL库?——实例详解及代码 在Python中,您可以通过调用DLL库完成各种功能,来满足不同的需求。调用DLL库意味着从外部获取了一些函数,可以在Python中直接调用这些函数,这对于Python程序员来说是一种非常有用的技能。本文将为大家介绍如何在Python中调用DLL库。

    2024年02月06日
    浏览(34)
  • 【Python微信机器人】第三篇:使用ctypes调用进程函数和读取内存结构体

    目前的系列目录(后面会根据实际情况变动): 在windows11上编译python 将python注入到其他进程并运行 注入Python并使用ctypes主动调用进程内的函数和读取内存结构体 使用汇编引擎调用进程内的任意函数 利用beaengine反汇编引擎的c接口写一个pyd库,用于实现inline hook 利用beaengine反汇编

    2024年02月06日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包