欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python調(diào)用C語言動態(tài)庫的方法小結(jié)

 更新時間:2024年12月27日 10:42:58   作者:TSFullStack  
這篇文章主要為大家詳細(xì)介紹了Python調(diào)用C語言動態(tài)庫的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,有需要的小伙伴可以參考一下

ctypes 是 Python 的外部函數(shù)庫。它提供了與 C 兼容的數(shù)據(jù)類型,并允許調(diào)用 DLL 或共享庫中的函數(shù)??墒褂迷撃K以純 Python 形式對這些庫進(jìn)行封裝。

基本數(shù)據(jù)類型對應(yīng)關(guān)系

[ctypes] 定義了一些和C兼容的基本數(shù)據(jù)類型:

ctypes 類型C 類型Python 類型
[c_bool]_Boolbool (1)
[c_char]char單字符字節(jié)串對象
[c_wchar]wchar_t單字符字符串
[c_byte]charint
[c_ubyte]unsigned charint
[c_short]shortint
[c_ushort]unsigned shortint
[c_int]intint
[c_uint]unsigned intint
[c_long]longint
[c_ulong]unsigned longint
[c_longlong]__int64 或 long longint
[c_ulonglong]unsigned __int64 或 unsigned long longint
[c_size_t]size_tint
[c_ssize_t]ssize_t 或 Py_ssize_tint
[c_float]floatfloat
[c_double]doublefloat
[c_longdouble]long doublefloat
[c_char_p]char * (NUL terminated)字節(jié)串對象或 None
[c_wchar_p]wchar_t * (NUL terminated)字符串或 None
[c_void_p]void *int 或 None

環(huán)境

開發(fā)工具:Clion

C語言版本:C11

Python版本:Python3.8

創(chuàng)建項目

CMakeLists.txt

# 指定 CMake 的最低版本要求
cmake_minimum_required(VERSION 3.30)

# 定義項目名稱和支持的語言類型
project(CLibSharedDemo C)

# 設(shè)置 C 標(biāo)準(zhǔn)版本為 C11
set(CMAKE_C_STANDARD 11)

# 添加共享庫目標(biāo),將 library.c 編譯為動態(tài)庫 (Windows 下為 .dll,Linux 下為 .so,macOS 下為 .dylib)
add_library(CLibSharedDemo SHARED library.c)

library.h

#ifndef CLIBSHAREDDEMO_LIBRARY_H
#define CLIBSHAREDDEMO_LIBRARY_H

#include <wchar.h>

void plus(int a, int *result);

void *process_void_pointer(void *ptr);

_Bool is_even(int num);

int add_int(int a, int b);

short add_short(short a, short b);

long add_long(long a, long b);

long long add_longlong(long long a, long long b);

unsigned int add_unsigned_int(unsigned int a, unsigned int b);

unsigned short add_unsigned_short(unsigned short a, unsigned short b);

unsigned long add_unsigned_long(unsigned long a, unsigned long b);

unsigned long long add_unsigned_longlong(unsigned long long a, unsigned long long b);

float add_float(float a, float b);

double add_double(double a, double b);

char to_upper(char c);

wchar_t to_upper_wchar(wchar_t wc);

char *copy_string(const char *src, char *dest);

wchar_t *copy_wstring(const wchar_t *src, wchar_t *dest);

size_t add_size_t(size_t a, size_t b);

ssize_t add_ssize_t(ssize_t a, ssize_t b);

void fill_array(int *arr, int size);

typedef struct {
    char name[50];
    int age;
} Person;

Person update_person_by_value(Person p);

void update_person_by_pointer(Person *p);

#endif //CLIBSHAREDDEMO_LIBRARY_H

library.c

#include "library.h"

#include <stdio.h>
#include <string.h>
#include <wchar.h>

// void
void plus(const int a, int *result) {
    *result = a + 1;
}

// void *
void *process_void_pointer(void *ptr) {
    return ptr;
}

// _Bool
_Bool is_even(const int num) {
    return num % 2 == 0;
}

// int
int add_int(const int a, const int b) {
    return a + b;
}

// short
short add_short(const short a, const short b) {
    return a + b;
}

// long
long add_long(const long a, const long b) {
    return a + b;
}

// long long
long long add_longlong(const long long a, const long long b) {
    return a + b;
}

// unsigned int
unsigned int add_unsigned_int(const unsigned int a, const unsigned int b) {
    return a + b;
}

// unsigned short
unsigned short add_unsigned_short(const unsigned short a, const unsigned short b) {
    return a + b;
}

// unsigned long
unsigned long add_unsigned_long(const unsigned long a, const unsigned long b) {
    return a + b;
}

// unsigned long long
unsigned long long add_unsigned_longlong(const unsigned long long a, const unsigned long long b) {
    return a + b;
}

// float
float add_float(const float a, const float b) {
    return a + b;
}

// double
double add_double(const double a, const double b) {
    return a + b;
}

// char
char to_upper(const char c) {
    if (c >= 'a' && c <= 'z') {
        return c - ('a' - 'A');
    }
    return c;
}

// wchar_t
wchar_t to_upper_wchar(const wchar_t wc) {
    if (wc >= L'a' && wc <= L'z') {
        return wc - (L'a' - L'A');
    }
    return wc;
}

// char *
char *copy_string(const char *src, char *dest) {
    strcpy(dest, src);
    return dest;
}

// wchar_t *
wchar_t *copy_wstring(const wchar_t *src, wchar_t *dest) {
    wcscpy(dest, src);
    return dest;
}

// size_t
size_t add_size_t(const size_t a, const size_t b) {
    return a + b;
}

// ssize_t
ssize_t add_ssize_t(const ssize_t a, const ssize_t b) {
    return a + b;
}


// arr
void fill_array(int *arr, int size) {
    for (int i = 0; i < size; i++) {
        arr[i] = arr[i] * i;
    }
}

// struct
Person update_person_by_value(Person p) {
    p.age += 1; // 修改 age
    return p;
}

void update_person_by_pointer(Person *p) {
    if (p != NULL) {
        p->age += 1; // 修改 age
    }
}

編譯

選擇菜單【Build】 - 【Build Project】,編譯生成動態(tài)庫在 cmake-build-debug 目錄下。

使用

# main.py

import ctypes
import platform

"""
官方參考文檔:https://docs.python.org/zh-cn/3.8/library/ctypes.html
"""

# 獲取當(dāng)前操作系統(tǒng)的名稱
current_platform = platform.system()

# 根據(jù)操作系統(tǒng)設(shè)置庫的路徑
if current_platform == "Windows":
    lib = ctypes.CDLL("./cmake-build-debug/libCLibSharedDemo.dll")  # Windows
elif current_platform == "Linux":
    lib = ctypes.CDLL("./cmake-build-debug/libCLibSharedDemo.so")  # Linux
elif current_platform == "Darwin":  # macOS的名稱是 Darwin
    lib = ctypes.CDLL("./cmake-build-debug/libCLibSharedDemo.dylib")  # macOS
else:
    raise OSError("Unsupported platform")

""" 空值 """

# void
lib.plus.argtypes = (ctypes.c_int, ctypes.POINTER(ctypes.c_int))
lib.plus.restype = None

result = ctypes.c_int()  # 創(chuàng)建一個 ctypes 整型變量作為結(jié)果
lib.plus(5, ctypes.byref(result))  # 使用 ctypes.byref 傳遞指針
print("void:", result.value)  # 輸出: Result: 6

# void *
lib.process_void_pointer.argtypes = (ctypes.c_void_p,)
lib.process_void_pointer.restype = ctypes.c_void_p

ptr = ctypes.pointer(ctypes.c_int(42))
print("void *: ", lib.process_void_pointer(ptr))  # 輸出: 2320620323976

""" 布爾 """

# _Bool -> c_bool
lib.is_even.argtypes = (ctypes.c_int,)
lib.is_even.restype = ctypes.c_bool
print("_Bool:", lib.is_even(4))  # 輸出: True

""" 整數(shù)/浮點數(shù) """

# int -> c_int
lib.add_int.argtypes = (ctypes.c_int, ctypes.c_int)
lib.add_int.restype = ctypes.c_int
print("int:", lib.add_int(10, 20))  # 輸出: 30

# short -> c_short
lib.add_short.argtypes = (ctypes.c_short, ctypes.c_short)
lib.add_short.restype = ctypes.c_short
print("short:", lib.add_short(3200, 10))  # 輸出: 3210

# long -> c_long
lib.add_long.argtypes = (ctypes.c_long, ctypes.c_long)
lib.add_long.restype = ctypes.c_long
print("long:", lib.add_long(10000, 2000))  # 輸出: 12000

# long long -> c_longlong
lib.add_longlong.argtypes = (ctypes.c_longlong, ctypes.c_longlong)
lib.add_longlong.restype = ctypes.c_longlong
print("long long:", lib.add_longlong(100000000000, 200000000000))  # 輸出: 300000000000

# unsigned int -> c_uint
lib.add_unsigned_int.argtypes = (ctypes.c_uint, ctypes.c_uint)
lib.add_unsigned_int.restype = ctypes.c_uint
print("unsigned int:", lib.add_unsigned_int(10, 20))  # 輸出: 30

# unsigned short -> c_ushort
lib.add_unsigned_short.argtypes = (ctypes.c_ushort, ctypes.c_ushort)
lib.add_unsigned_short.restype = ctypes.c_ushort
print("unsigned short:", lib.add_unsigned_short(3200, 10))  # 輸出: 3210

# unsigned long -> c_ulong
lib.add_unsigned_long.argtypes = (ctypes.c_ulong, ctypes.c_ulong)
lib.add_unsigned_long.restype = ctypes.c_ulong
print("unsigned long:", lib.add_unsigned_long(10000, 2000))  # 輸出: 12000

# unsigned long long -> c_ulonglong
lib.add_unsigned_longlong.argtypes = (ctypes.c_ulonglong, ctypes.c_ulonglong)
lib.add_unsigned_longlong.restype = ctypes.c_ulonglong
print("unsigned long long:", lib.add_unsigned_longlong(100000000000, 200000000000))  # 輸出: 300000000000

# float -> c_float
lib.add_float.argtypes = (ctypes.c_float, ctypes.c_float)
lib.add_float.restype = ctypes.c_float
print("float:", lib.add_float(3.5, 2.0))  # 輸出: 5.5

# double -> c_double
lib.add_double.argtypes = (ctypes.c_double, ctypes.c_double)
lib.add_double.restype = ctypes.c_double
print("double:", lib.add_double(1.5, 2.5))  # 輸出: 4.0

""" 字符/字符串 """

# char -> c_char
lib.to_upper.argtypes = (ctypes.c_char,)
lib.to_upper.restype = ctypes.c_char
print("char:", lib.to_upper("a".encode()).decode())  # 輸出: 'A'

# wchar_t -> c_wchar
lib.to_upper_wchar.argtypes = (ctypes.c_wchar,)
lib.to_upper_wchar.restype = ctypes.c_wchar
print("wchar_t:", lib.to_upper_wchar("a"))  # 輸出: 'A'

# char * -> c_char_p
lib.copy_string.argtypes = (ctypes.c_char_p, ctypes.c_char_p)
lib.copy_string.restype = ctypes.c_char_p

src_str = "Hello"
dest_str = ctypes.create_string_buffer(100)  # 預(yù)留 100 字節(jié)緩沖區(qū)
result = lib.copy_string(src_str.encode(), dest_str)
print("char *:", result.decode())  # 輸出: 'Hello'

# wchar_t * -> c_wchar_p
lib.copy_wstring.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p)
lib.copy_wstring.restype = ctypes.c_wchar_p

src_wstr = "Hello Wide"
dest_wstr = ctypes.create_unicode_buffer(100)  # 預(yù)留 100 個寬字符緩沖區(qū)
result = lib.copy_wstring(src_wstr, dest_wstr)
print("wchar_t *:", result)  # 輸出: 'Hello Wide'

""" 指針 """

# int * -> ctypes.POINTER(ctypes.c_int)
lib.plus.argtypes = (ctypes.c_int, ctypes.POINTER(ctypes.c_int))
lib.plus.restype = None

result = ctypes.c_int()
lib.plus(5, ctypes.byref(result))  # ctypes.byref 直接傳遞原有變量的地址
print("int *:", result.value)  # 輸出: Result: 6

result = ctypes.c_int()
lib.plus(5, ctypes.pointer(result))  # ctypes.pointer 顯式地創(chuàng)建一個指針對象
print("int *:", result.value)  # 輸出: Result: 6

""" 內(nèi)存大小 """

# size_t -> c_size_t
lib.add_size_t.argtypes = (ctypes.c_size_t, ctypes.c_size_t)
lib.add_size_t.restype = ctypes.c_size_t
print("size_t:", lib.add_size_t(10, 20))  # 輸出: 30

# ssize_t -> c_ssize_t
lib.add_ssize_t.argtypes = (ctypes.c_ssize_t, ctypes.c_ssize_t)
lib.add_ssize_t.restype = ctypes.c_ssize_t
print("ssize_t:", lib.add_ssize_t(10, 20))  # 輸出: 30


""" 數(shù)組 """

lib.fill_array.argtypes = (ctypes.POINTER(ctypes.c_int), ctypes.c_int)
lib.fill_array.restype = None

ls = [1, 3, 5]
arr = (ctypes.c_int * len(ls))(*ls)
lib.fill_array(arr, len(arr))
print("array:", list(arr))  # array: [0, 3, 10]

""" 結(jié)構(gòu)體 """


class Person(ctypes.Structure):
    _fields_ = [("name", ctypes.c_char * 50), ("age", ctypes.c_int)]


# 情況 1:入?yún)⒑头祷刂刀际墙Y(jié)構(gòu)體
lib.update_person_by_value.argtypes = (Person,)
lib.update_person_by_value.restype = Person

person1 = Person(name="Alice".encode(), age=25)
print(f"Before (Value): name={person1.name.decode()}, age={person1.age}")
updated_person = lib.update_person_by_value(person1)
print(f"After (Value): name={updated_person.name.decode()}, age={updated_person.age}")

# 情況 2:入?yún)榻Y(jié)構(gòu)體指針
lib.update_person_by_pointer.argtypes = (ctypes.POINTER(Person),)
lib.update_person_by_pointer.restype = None

person2 = Person(name="Bob".encode(), age=30)
print(f"Before (Pointer): name={person2.name.decode()}, age={person2.age}")
lib.update_person_by_pointer(ctypes.byref(person2))
print(f"After (Pointer): name={person2.name.decode()}, age={person2.age}")

到此這篇關(guān)于Python調(diào)用C語言動態(tài)庫的方法小結(jié)的文章就介紹到這了,更多相關(guān)Python調(diào)用C語言動態(tài)庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python獲取接口數(shù)據(jù)的實現(xiàn)示例

    Python獲取接口數(shù)據(jù)的實現(xiàn)示例

    本文主要介紹了Python獲取接口數(shù)據(jù)的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • python中plt.imshow與cv2.imshow顯示顏色問題

    python中plt.imshow與cv2.imshow顯示顏色問題

    這篇文章主要介紹了plt.imshow與cv2.imshow顯示顏色問題,本文給大家介紹的非常詳細(xì),同時給大家提到了cv2.imshow()和plt.imshow()的區(qū)別講解,需要的朋友可以參考下
    2020-07-07
  • 如何實現(xiàn)Python調(diào)用Golang代碼詳解

    如何實現(xiàn)Python調(diào)用Golang代碼詳解

    這篇文章主要介紹了如何實現(xiàn)Python調(diào)用Golang代碼,Python和Golang都是當(dāng)下非常流行的編程語言,在實際開發(fā)中,我們可能會遇到需要將Python和Golang進(jìn)行組合使用的場景,感興趣想要詳細(xì)了解可以參考下文
    2023-05-05
  • Python標(biāo)準(zhǔn)庫之typing的用法(類型標(biāo)注)

    Python標(biāo)準(zhǔn)庫之typing的用法(類型標(biāo)注)

    這篇文章主要介紹了Python標(biāo)準(zhǔn)庫之typing的用法(類型標(biāo)注),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • python通過http下載文件的方法詳解

    python通過http下載文件的方法詳解

    這篇文章主要介紹了python通過http下載文件的方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • Python tkinter的grid布局及Text動態(tài)顯示方法

    Python tkinter的grid布局及Text動態(tài)顯示方法

    今天小編就為大家分享一篇Python tkinter的grid布局及Text動態(tài)顯示方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • Python GUI編程之tkinter模塊Toplevel控件實現(xiàn)搭建父子窗口

    Python GUI編程之tkinter模塊Toplevel控件實現(xiàn)搭建父子窗口

    這篇文章主要介紹了Python使用tkinter模塊Toplevel控件搭建父子窗口的實現(xiàn)方法,Tkinter是Python的標(biāo)準(zhǔn)GUI庫,Python使用Tkinter可以快速的創(chuàng)建GUI應(yīng)用程序,用到相關(guān)控件的同學(xué)可以參考下
    2023-12-12
  • 詳解python單元測試框架unittest

    詳解python單元測試框架unittest

    本篇文章給大家詳解了python單元測試框架unittest的相關(guān)知識點,有興趣的朋友參考學(xué)習(xí)下。
    2018-07-07
  • python 用所有標(biāo)點符號分隔句子的示例

    python 用所有標(biāo)點符號分隔句子的示例

    今天小編就為大家分享一篇python 用所有標(biāo)點符號分隔句子的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • django多種支付、并發(fā)訂單處理實例代碼

    django多種支付、并發(fā)訂單處理實例代碼

    在本篇文章里小編給大家整理的是關(guān)于django多種支付、并發(fā)訂單處理實例代碼,需要的朋友們可以學(xué)習(xí)下。
    2019-12-12

最新評論