最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中調(diào)用C++代碼的方法總結(jié)

 更新時(shí)間:2025年11月18日 08:34:49   作者:夢(mèng)_魚(yú)  
這篇文章主要為大家詳細(xì)介紹了Python中調(diào)用C++代碼的相關(guān)方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下

1. extern "C" {} 包裹導(dǎo)出函數(shù)

// C++ 中存在名稱修飾,通過(guò) extern "C" {} 將C++函數(shù)導(dǎo)出為C函數(shù)
// 1. 為類的每個(gè)函數(shù)創(chuàng)建C風(fēng)格接口,第一個(gè)參數(shù)為對(duì)象指針
// 2. 提供 create(構(gòu)造) destroy(析構(gòu)) 函數(shù)管理對(duì)象的生命周期
#include <string>

// C++類定義
class Calculator {
private:
int base;
public:
Calculator(int b) : base(b) {}
int add(int a) { return base + a; }
std::string greet(const std::string& name) { return "Hello, " + name; }
};

// C風(fēng)格函數(shù)
extern "C" {

// 創(chuàng)建對(duì)象(對(duì)應(yīng)構(gòu)造函數(shù))
Calculator* Calculator_create(int base) {
return new Calculator(base);
}

// 銷毀對(duì)象(對(duì)應(yīng)析構(gòu)函數(shù))
void Calculator_destroy(Calculator* obj) {
delete obj;
}

// 封裝成員函數(shù)
int Calculator_add(Calculator* obj, int a) {
return obj->add(a);
}

// 字符串處理需要特殊轉(zhuǎn)換(C++ string -> char*)
const char* Calculator_greet(Calculator* obj, const char* name) {
static std::string result;  // 注意:靜態(tài)變量在多線程中不安全
result = obj->greet(std::string(name));
return result.c_str();
}

}

2. 將C++代碼編譯為動(dòng)態(tài)庫(kù)

# 使用C++編譯器,保留 -f PIC -shared 參數(shù)生成位置無(wú)關(guān)的動(dòng)態(tài)庫(kù)
g++ -shared -fPIC -o libcalc.so example.cpp

3.python ctypes調(diào)用動(dòng)態(tài)庫(kù)

使用python的ctypes庫(kù)調(diào)用動(dòng)態(tài)庫(kù)(加載動(dòng)態(tài)庫(kù) -> 定義C函數(shù)的輸入?yún)?shù)與返回參數(shù) -> 調(diào)用動(dòng)態(tài)庫(kù)函數(shù))

  • 用 c_void_p 類型存儲(chǔ)C++對(duì)象的指針
  • 字符串通過(guò)bytes類型轉(zhuǎn)換(encode/decode)
  • 實(shí)現(xiàn) del 方法自動(dòng)釋放C++對(duì)象,避免內(nèi)存泄漏
import ctypes
import os


class CalculatorWrapper:
    """C++ Calculator類的Python封裝器"""

    def __init__(self):
        # 加載動(dòng)態(tài)庫(kù)
        self.lib = self._load_library()
        # 配置C接口函數(shù)原型
        self._setup_functions()
        # 存儲(chǔ)C++對(duì)象指針
        self.obj_ptr = None

    def _load_library(self):
        """根據(jù)操作系統(tǒng)加載對(duì)應(yīng)的庫(kù)文件"""
        try:
            if os.name == "nt":
                return ctypes.CDLL("./calc.dll")
            elif os.name == "posix":
                return ctypes.CDLL("./libcalc.so")
            else:
                raise OSError("不支持的操作系統(tǒng)")
        except OSError as e:
            raise RuntimeError(f"加載庫(kù)失敗: {e}")

    def _setup_functions(self):
        """定義C接口函數(shù)的參數(shù)類型和返回值類型"""
        # 創(chuàng)建對(duì)象
        self.lib.Calculator_create.argtypes = [ctypes.c_int]
        self.lib.Calculator_create.restype = ctypes.c_void_p  # 返回對(duì)象指針

        # 銷毀對(duì)象
        self.lib.Calculator_destroy.argtypes = [ctypes.c_void_p]
        self.lib.Calculator_destroy.restype = None

        # 加法函數(shù)
        self.lib.Calculator_add.argtypes = [ctypes.c_void_p, ctypes.c_int]
        self.lib.Calculator_add.restype = ctypes.c_int

        # 字符串問(wèn)候函數(shù)
        self.lib.Calculator_greet.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
        self.lib.Calculator_greet.restype = ctypes.c_char_p

    def create(self, base_value):
        """創(chuàng)建C++ Calculator實(shí)例"""
        self.obj_ptr = self.lib.Calculator_create(base_value)
        if not self.obj_ptr:
            raise RuntimeError("創(chuàng)建C++對(duì)象失敗")

    def add(self, a):
        """調(diào)用加法方法"""
        self._check_object()
        return self.lib.Calculator_add(self.obj_ptr, a)

    def greet(self, name):
        """調(diào)用問(wèn)候方法(處理字符串轉(zhuǎn)換)"""
        self._check_object()
        # Python字符串轉(zhuǎn)C字符串(bytes類型)
        c_name = name.encode('utf-8')
        result_ptr = self.lib.Calculator_greet(self.obj_ptr, c_name)
        # C字符串轉(zhuǎn)Python字符串
        return result_ptr.decode('utf-8')

    def _check_object(self):
        """檢查對(duì)象是否已創(chuàng)建"""
        if not self.obj_ptr:
            raise RuntimeError("請(qǐng)先調(diào)用create()創(chuàng)建對(duì)象")

    def __del__(self):
        """對(duì)象銷毀時(shí)自動(dòng)釋放C++資源"""
        if self.obj_ptr:
            self.lib.Calculator_destroy(self.obj_ptr)


if __name__ == "__main__":
    try:
        calc = CalculatorWrapper()
        calc.create(100)  # 初始化base值為100

        print(f"100 + 50 = {calc.add(50)}")  # 輸出150
        print(calc.greet("C++"))  # 輸出"Hello, Python"
    except Exception as e:
        print(f"錯(cuò)誤: {e}")

4.方法補(bǔ)充

以下是小編整理的Python調(diào)用C++代碼的其他方法,大家可以參考一下

使用ctypes調(diào)用C/C++代碼

編寫(xiě)C/C++代碼

首先,我們編寫(xiě)一個(gè)簡(jiǎn)單的C++函數(shù),并將其編譯為共享庫(kù)(.so文件)。

// mylib.cpp
#include <iostream>
extern "C" {
    int add(int a, int b) {
        std::cout << "add called" << std::endl;
        return a + b;
    }
}

編譯C/C++代碼

使用以下命令將C++代碼編譯為共享庫(kù):

g++ -shared -o libmylib.so -fPIC mylib.cpp
  • -shared:生成共享庫(kù)。
  • -o libmylib.so:指定輸出文件名為libmylib.so。
  • -fPIC:生成位置無(wú)關(guān)代碼(Position Independent Code),這是共享庫(kù)所必需的。

在Python中調(diào)用C/C++函數(shù)

使用ctypes庫(kù)加載共享庫(kù)并調(diào)用C++函數(shù):

import ctypes
import os

# 加載共享庫(kù)
lib = ctypes.CDLL(os.path.abspath("libmylib.so"))

# 調(diào)用 C++ 函數(shù)
result = lib.add(3, 4)  # add called
print(f"Result: {result}")  # 輸出: Result: 7

使用pybind11調(diào)用C/C++代碼

需要 pip install pybind11

pybind11 的名字中的 11 表示它需要 C++11 或更高版本 的支持

編寫(xiě)C/C++代碼

pybind11是一個(gè)輕量級(jí)的C++庫(kù),用于將C++代碼暴露給Python。我們編寫(xiě)一個(gè)簡(jiǎn)單的C++函數(shù),并使用pybind11將其綁定到Python。

// mylib_pybind.cpp
#include <pybind11/pybind11.h>
#include <iostream>

int add(int a, int b) {
    std::cout << "add called from pybind" << std::endl;
    return a + b;
}

PYBIND11_MODULE(mylib_pybind, m) {
    m.def("add", &add, "A function that adds two numbers");
}

編譯C/C++代碼

使用以下命令將C++代碼編譯為Python模塊:

c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) mylib_pybind.cpp -o mylib_pybind$(python3-config --extension-suffix)

生成了 mylib_pybind.cpython-311-x86_64-linux-gnu.so 文件

  • -O3:優(yōu)化級(jí)別為3,生成高度優(yōu)化的代碼。
  • -Wall:?jiǎn)⒂盟芯妗?/li>
  • -shared:生成共享庫(kù)。
  • -std=c++11:使用C++11標(biāo)準(zhǔn)。
  • -fPIC:生成位置無(wú)關(guān)代碼。
  • $(python3 -m pybind11 --includes):獲取pybind11的頭文件路徑。
  • -o mylib_pybind$(python3-config --extension-suffix):指定輸出文件名,并使用Python的擴(kuò)展名后綴。

在Python中調(diào)用C/C++函數(shù)

import mylib_pybind as mylib

result = mylib.add(3, 4)  # add called from pybind
print(f"Result: {result}")  # 輸出: Result: 7

c++調(diào)用python代碼

# example.py
def add(a, b):
    return a + b
#include <pybind11/embed.h>  // 嵌入 Python 解釋器
#include <iostream>

namespace py = pybind11;

int main() {
    // 啟動(dòng) Python 解釋器
    py::scoped_interpreter guard{};

    // 導(dǎo)入 Python 模塊
    py::module_ example = py::module_::import("example");

    // 調(diào)用 Python 函數(shù)
    py::object result = example.attr("add")(3, 4);
    std::cout << "Result: " << result.cast<int>() << std::endl;  // 輸出: Result: 7

    return 0;
}
g++ -o call_py call_py.cpp -I/opt/conda/envs/ai/include/python3.10/ $(python3 -m pybind11 --includes) -L/opt/conda/envs/ai/lib -lpython3.10

echo 'export LD_LIBRARY_PATH=/opt/conda/envs/ai/lib:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc

執(zhí)行 ./call_py

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

相關(guān)文章

  • python中urllib模塊用法實(shí)例詳解

    python中urllib模塊用法實(shí)例詳解

    這篇文章主要介紹了python中urllib模塊用法,以實(shí)例形式詳細(xì)分析了python中urllib模塊代替PHP的curl操作方法,具有不錯(cuò)的借鑒價(jià)值,需要的朋友可以參考下
    2014-11-11
  • OpenCV半小時(shí)掌握基本操作之腐蝕膨脹

    OpenCV半小時(shí)掌握基本操作之腐蝕膨脹

    這篇文章主要介紹了OpenCV基本操作之腐蝕膨脹,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Blender?Python編程實(shí)現(xiàn)批量導(dǎo)入網(wǎng)格并保存渲染圖像

    Blender?Python編程實(shí)現(xiàn)批量導(dǎo)入網(wǎng)格并保存渲染圖像

    這篇文章主要為大家介紹了Blender?Python?編程實(shí)現(xiàn)批量導(dǎo)入網(wǎng)格并保存渲染圖像示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • python銀行系統(tǒng)實(shí)現(xiàn)源碼

    python銀行系統(tǒng)實(shí)現(xiàn)源碼

    這篇文章主要為大家詳細(xì)介紹了python銀行系統(tǒng)實(shí)現(xiàn)源碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • Python實(shí)現(xiàn)刪除Android工程中的冗余字符串

    Python實(shí)現(xiàn)刪除Android工程中的冗余字符串

    這篇文章主要介紹了Python實(shí)現(xiàn)刪除Android工程中的冗余字符串,本文實(shí)現(xiàn)的是刪除Android資源(語(yǔ)言)國(guó)際化機(jī)制中的一些冗余字符串,需要的朋友可以參考下
    2015-01-01
  • Pycharm常用快捷鍵總結(jié)及配置方法

    Pycharm常用快捷鍵總結(jié)及配置方法

    這篇文章主要介紹了Pycharm常用快捷鍵總結(jié)及配置方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • python 簡(jiǎn)單的股票基金爬蟲(chóng)

    python 簡(jiǎn)單的股票基金爬蟲(chóng)

    最近基金非?;鸨芏嘣静煌顿Y、不理財(cái)人,也開(kāi)始討論、參與買基金了。根據(jù)投資對(duì)象的不同,基金分為股票型基金、債券基金、混合型基金、貨幣基金。所以今天我們就來(lái)看看,這些基金公司都喜歡買那些公司的股票。
    2021-06-06
  • Python 稀疏矩陣-sparse 存儲(chǔ)和轉(zhuǎn)換

    Python 稀疏矩陣-sparse 存儲(chǔ)和轉(zhuǎn)換

    這篇文章主要介紹了Python 稀疏矩陣-sparse 存儲(chǔ)和轉(zhuǎn)換的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Python3.5內(nèi)置模塊之shelve模塊、xml模塊、configparser模塊、hashlib、hmac模塊用法分析

    Python3.5內(nèi)置模塊之shelve模塊、xml模塊、configparser模塊、hashlib、hmac模塊用法

    這篇文章主要介紹了Python3.5內(nèi)置模塊之shelve模塊、xml模塊、configparser模塊、hashlib、hmac模塊,結(jié)合實(shí)例形式較為詳細(xì)的分析了shelve、xml、configparser、hashlib、hmac等模塊的功能及使用方法,需要的朋友可以參考下
    2019-04-04
  • Python強(qiáng)化練習(xí)之PyTorch opp算法實(shí)現(xiàn)月球登陸器

    Python強(qiáng)化練習(xí)之PyTorch opp算法實(shí)現(xiàn)月球登陸器

    在面向?qū)ο蟪霈F(xiàn)之前,我們采用的開(kāi)發(fā)方法都是面向過(guò)程的編程(OPP)。面向過(guò)程的編程中最常用的一個(gè)分析方法是“功能分解”。我們會(huì)把用戶需求先分解成模塊,然后把模塊分解成大的功能,再把大的功能分解成小的功能,整個(gè)需求就是按照這樣的方式,最終分解成一個(gè)一個(gè)的函數(shù)
    2021-10-10

最新評(píng)論

洞口县| 瓦房店市| 高要市| 仪陇县| 扎赉特旗| 绥江县| 沂南县| 黄骅市| 洛隆县| 高密市| 老河口市| 霍林郭勒市| 靖西县| 彰武县| 渑池县| 宕昌县| 大冶市| 醴陵市| 宁乡县| 遂川县| 闽侯县| 富民县| 祥云县| 左云县| 奉化市| 方城县| 平乡县| 准格尔旗| 虹口区| 婺源县| 罗田县| 阳春市| 比如县| 乌兰县| 祥云县| 鲁山县| 金山区| 库车县| 永胜县| 开化县| 满城县|