ctypes库介绍
ctypes是Python的一个外部库,它提供了一种灵活的方式来调用C语言的动态链接库(DLL)或共享库(SO)。通过ctypes,我们可以在Python中直接调用C语言编写的函数和变量,从而实现跨语言的互操作。
ctypes 它提供了与 C 兼容的数据类型,并允许调用 DLL 或共享库中的函数。可使用该模块以纯 Python 形式对这些库进行封装。
ctypes提供的方法和C语言对应的数据类型如下表:
ctypes --- Python 的外部函数库 — Python 3.12.1 文档
ctypes — A foreign function library for Python — Python 3.12.1 documentation
默认情况下都会假定函数返回 C int 类型。 其他返回类型可通过设置函数对象的 restype 属性来指定。
使用ctypes的基本步骤如下:
- 导入ctypes库
- 加载动态链接库或共享库
- 定义函数原型
- 调用函数
创建C++ 动态库
如何通过VS 2022创建C++动态连接库,可以阅读:[C++] VS 2022演练 - 创建和使用用动态连接库(DLL) (详细图文)-CSDN博客
这里是我创建好的MathLibrary动态链接库:
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无法找到对应的函数,如下图所示:
在C++中,extern "C"是一个链接指示符,用于告诉编译器按照C语言的方式进行编译。这意味着在C++代码中使用extern "C"声明的函数或变量将被当作C语言的函数或变量进行处理,而不会被当作C++的函数或变量进行处理。
extern "C"的作用主要有以下几点:
保持函数名和变量名的C语言兼容性。在C++中,函数名和变量名默认会添加前缀“_”,而在C语言中则不会。使用extern "C"可以避免这种情况的发生。
保持函数参数类型的C语言兼容性。在C++中,函数参数类型可能会被自动推导为模板类型,而在C语言中则不会。使用extern "C"可以避免这种情况的发生。
保持函数调用约定的C语言兼容性。在C++中,函数调用约定可能会有所不同,如stdcall、cdecl等,而在C语言中则只有一种调用约定。使用extern "C"可以避免这种情况的发生。
与某些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调用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语句。
文章来源:https://www.toymoban.com/news/detail-805746.html
当然,你也可以直接把上面的代码保存为.py文件,然后放在MathLibrary.dll相同的目录下,直接通过python运行.py文件。文章来源地址https://www.toymoban.com/news/detail-805746.html
到了这里,关于[Python] 如何通过ctypes库来调用C++ 动态库 DLL?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!