C++在Linux上生成動態庫并調用接口測試

加減乘除demo代碼

項目結構

CPP/

├── calculator.cpp

├── calculator.h

├── main.cpp

頭文件

#ifndef CALCULATOR_H
#define CALCULATOR_H#ifdef __cplusplus
extern "C" {#endifdouble add(double a, double b);double subtract(double a, double b);double multiply(double a, double b);double divide(double a, double b);#ifdef __cplusplus
}
#endif#endif // CALCULATOR_H

源文件

#include "calculator.h"
#include <iostream>double add(double a, double b) {return a + b;
}double subtract(double a, double b) {return a - b;
}double multiply(double a, double b) {return a * b;
}double divide(double a, double b) {if (b == 0) {std::cerr << "錯誤:除數不能為0!" << std::endl;return 0;}return a / b;
}

main.cpp測試

main.cpp,用于測試動態庫接口,需要在編譯好動態庫后進行測試

#include <iostream>
#include "calculator.h"int main() {double a = 8, b = 2;std::cout << "加法: " << add(a, b) << std::endl;std::cout << "減法: " << subtract(a, b) << std::endl;std::cout << "乘法: " << multiply(a, b) << std::endl;std::cout << "除法: " << divide(a, b) << std::endl;return 0;
}

編譯動態庫

  1. -fPIC:為共享庫生成位置無關代碼
  2. -shared:生成共享庫
  3. -o libcalculator.so:輸出為動態庫文件
g++ -fPIC -shared calculator.cpp -o libcalculator.so

查看動態庫有哪些接口

nm命令

nm -D libcalculator.so

帶有 T 的(代表函數定義在庫里)

信息比較多可以加grep命令進行過濾

objdump命令

objdump -T libcalculator.so

readelf命令

readelf -Ws libcalculator.so

main.cpp編譯

main.cpp會在編譯的過程中去動態鏈接libcalculator.so

  1. -L.:告訴編譯器去當前目錄查找庫文件
  2. -lcalculator:鏈接名為 libcalculator.so 的庫(省略前綴 lib 和擴展名 .so
g++ main.cpp -L. -lcalculator -o main

執行測試程序

運行程序前,設置動態庫路徑

  1. LD_LIBRARY_PATH 是 Linux 下指定“運行時動態庫查找路徑”的環境變量
  2. . 代表當前目錄
  3. $LD_LIBRARY_PATH 是保留已有路徑
#設置環境變量
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

上面代碼的意思是:請系統在當前目錄找動態庫,然后再去默認路徑找

系統默認會查找這些路徑

  1. /lib
  2. /usr/lib

永久添加路徑

更新系統的動態鏈接庫緩存,也就是告訴系統有哪些 .so 庫、它們在哪兒,以便程序運行時可以找到這些庫。

sudo ldconfig
什么時候用?
  1. 安裝了新的 .so 動態庫
  2. .so 文件放到了非標準路徑下(比如 /usr/local/lib/opt/mylibs
  3. 修改了 /etc/ld.so.conf/etc/ld.so.conf.d/ 下的配置

運行程序

./main

運行程序前,為什么要設置動態庫路徑

因為你用的是 動態鏈接庫(**.so**** 文件),程序運行時需要知道這個庫在哪里**。編譯的時候你告訴了編譯器怎么找到它(-L.),但運行時要靠系統的**動態鏈接器(ld.so)**來加載 .so 文件。

如果 .so 不在系統默認的路徑里(比如 /lib, /usr/lib),就需要你手動告訴它去哪里找。

python調用

test_calculator.py

import ctypes
import os# 加載動態庫
lib_path = os.path.abspath("libcalculator.so")
calculator = ctypes.CDLL(lib_path)# 設置參數和返回類型
calculator.add.argtypes = [ctypes.c_double, ctypes.c_double]
calculator.add.restype = ctypes.c_doublecalculator.subtract.argtypes = [ctypes.c_double, ctypes.c_double]
calculator.subtract.restype = ctypes.c_doublecalculator.multiply.argtypes = [ctypes.c_double, ctypes.c_double]
calculator.multiply.restype = ctypes.c_doublecalculator.divide.argtypes = [ctypes.c_double, ctypes.c_double]
calculator.divide.restype = ctypes.c_double# 測試調用
a = 10.0
b = 2.0print("加法:", calculator.add(a, b))
print("減法:", calculator.subtract(a, b))
print("乘法:", calculator.multiply(a, b))
print("除法:", calculator.divide(a, b))

測試調用

  1. export LD_LIBRARY_PATH=CPP:$LD_LIBRARY_PATH
  2. python3 test_calculator.py

Makefile生成動態庫

# Makefile for building libcalculator.so shared library# 編譯器
CXX = g++# 編譯選項
CXXFLAGS = -fPIC -Wall -Wextra -O2# 目標名稱
TARGET = libcalculator.so# 源碼文件
SRC = calculator.cpp# 頭文件
HEADER = calculator.h# 輸出路徑(當前目錄)
OBJ = $(SRC:.cpp=.o)# 默認目標
all: $(TARGET)# 生成共享庫
$(TARGET): $(OBJ)$(CXX) -shared -o $@ $^# 編譯cpp為.o文件
%.o: %.cpp $(HEADER)$(CXX) $(CXXFLAGS) -c $< -o $@# 清理生成的文件
clean:rm -f $(OBJ) $(TARGET).PHONY: all clean

運行make

Makefile一起生成動態庫和可執行程序

# 編譯器
CXX = g++# 編譯選項
CXXFLAGS = -fPIC -Wall -Wextra -O2# 生成共享庫的目標
LIB_NAME = libcalculator.so# 可執行文件名
EXEC = main# 源文件
LIB_SRC = calculator.cpp
MAIN_SRC = main.cpp# 對應的中間目標
LIB_OBJ = $(LIB_SRC:.cpp=.o)
MAIN_OBJ = $(MAIN_SRC:.cpp=.o)# 默認目標
all: $(LIB_NAME) $(EXEC)# 生成共享庫
$(LIB_NAME): $(LIB_OBJ)$(CXX) -shared -o $@ $^# 編譯 main,鏈接動態庫
$(EXEC): $(MAIN_OBJ) $(LIB_NAME)$(CXX) -o $@ $(MAIN_OBJ) -L. -lcalculator# 通用規則:.cpp -> .o
%.o: %.cpp$(CXX) $(CXXFLAGS) -c $< -o $@# 運行程序
run: allLD_LIBRARY_PATH=. ./$(EXEC)# 清理
clean:rm -f *.o $(LIB_NAME) $(EXEC).PHONY: all run clean

運行make

用CMakeLists管理

項目結構

CPP/

├── calculator.cpp

├── calculator.h

├── main.cpp

└── CMakeLists.txt

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(CalculatorProject)# 設置 C++ 標準
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)# 輸出到 build 目錄下的 bin 和 lib 子目錄
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)# 添加庫(生成 libcalculator.so)
add_library(calculator SHARED calculator.cpp)# 添加可執行文件
add_executable(main main.cpp)# 鏈接共享庫
target_link_libraries(main PRIVATE calculator)# 設置頭文件搜索路徑
target_include_directories(main PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(calculator PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

使用方法

  1. mkdir build && cd build
  2. cmake …
  3. cmake --build .

目錄結構

CPP/

├── calculator.cpp

├── calculator.h

├── main.cpp

├── CMakeLists.txt

└── build/

├── bin/│   └── main└── lib/└── libcalculator.so

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/77677.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/77677.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/77677.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

離線密碼生成器:安全可靠的密碼管理解決方案

離線密碼生成器&#xff1a;安全可靠的密碼管理解決方案 在當今數字時代&#xff0c;我們每天都需要使用各種網站和應用程序&#xff0c;每個賬戶都需要一個強密碼來保護我們的個人信息和隱私。然而&#xff0c;記住多個復雜的密碼幾乎是不可能的任務。今天&#xff0c;我要向…

ChatRex: Taming Multimodal LLM for Joint Perception and Understanding 論文理解和翻譯

一、TL&#xff1b;DR MLLM在感知方面存在不足&#xff08;遠遠比不上專家模型&#xff09;&#xff0c;比如Qwen2-VL在coco上recall只有43.9%提出了ChatRex&#xff0c;旨在從模型設計和數據開發兩個角度來填補這一感知能力的缺口ChatRex通過proposal邊界框輸入到LLM中將其轉…

自動駕駛技術-相機_IMU時空標定

自動駕駛技術-相機_IMU時空標定 時間延遲 時間延遲 參考鏈接1、2 相機主要分為全局和卷簾快門相機&#xff0c;從觸發到成像的過程包括&#xff1a;復位時間、AE()曝光時間、讀出時間 全局快門如下圖所示 卷簾快門如下圖所示 相機錄制視頻時&#xff0c;為了保持固定頻率&am…

Vue3 + Vite + TS,使用 Web Worker,web worker進階 hooks

worker 具體通訊方式 1.由 web page 發送消息- worker.postMessage(發送數據) 2.web worker 接收消息并執行相關邏輯- onmessage (e) > { 接收數據并處理邏輯postMessage(傳遞處理后的數據)} 3.由 web page 監聽 worker 消息&#xff0c;包括&#xff1a;- 處理數據的監聽…

AIDD-人工智能藥物設計-AI 精準預測蛋白質變構位點

Allo-PED: AI 精準預測蛋白質變構位點 目錄 Allo-PED 框架融合蛋白質語言模型與結構特征,顯著提高了變構位點預測的準確性和泛化能力。EcoFoldDB 利用蛋白質結構信息,為宏基因組提供了精確且可擴展的生態功能注釋新方法,顯著提升了對未知微生物功能的認知。上下文分子適配(…

1558 找素數

1558 找素數 ??難度&#xff1a;中等 &#x1f31f;考點&#xff1a;質數 &#x1f4d6; &#x1f4da; import java.util.Scanner; import java.util.Arrays;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int a sc.…

Nacos 提供了哪些服務的保護機制?

當面試官問這個問題時&#xff0c;大家一定要保持頭腦清醒&#xff0c;不要被帶跑偏了&#xff0c;Nacos 本身的核心定位是服務發現和配置管理中心&#xff0c;它并不直接提供像服務熔斷、服務限流、服務降級、請求重試 這類完整的、開箱即用的客戶端/網關級服務保護&#xff0…

【家政平臺開發(38)】解鎖家政平臺國際化密碼:多語言支持開發實戰

> 本【家政平臺開發】專欄聚焦家政平臺從 0 到 1 的全流程打造。從前期需求分析,剖析家政行業現狀、挖掘用戶需求與梳理功能要點,到系統設計階段的架構選型、數據庫構建,再到開發階段各模塊逐一實現。涵蓋移動與 PC 端設計、接口開發及性能優化,測試階段多維度保障平臺質…

DirectX12 - 基本知識 - 圖形驅動的本質

這里是SunshineBooming&#xff0c;GPU公司一枚小小的Driver工程師&#xff0c;主要工作是寫DirectX12 Driver&#xff0c;我會持續更新這個DX12 Spec系列&#xff0c;可能比較冷門&#xff0c;但是都是干貨和工作中的心得體會&#xff0c;有任何GPU相關的問題都可以在評論區互…

selenium元素獲取

from selenium import webdriver from selenium.webdriver.common.by import Bydriver webdriver.Chrome()driver.maximize_window()#最大化窗口 #隱式等待 driver.implicitly_wait(10)#打開網頁 driver.get("https://www.zhipin.com/beijing/?kacity-sites-101010100&q…

生物化學筆記:醫學免疫學原理15 超敏反應過敏反應(I型[蚊蟲叮咬]+II型[新生兒溶血癥、突眼型甲亢]+III型+IV型)

超敏反應 每個人都可能發生的過敏問題&#xff1a;被蚊子咬后起包 I型超敏反應 II型超敏反應 新生兒溶血癥分為Rh血型不合和ABO血型不合兩種情況。Rh血型不合通常從第二胎開始更容易發病&#xff0c;因為母體初次接觸Rh陽性胎兒的紅細胞后會產生抗D抗體&#xff0c;而這個致敏…

【android bluetooth 框架分析 02】【Module詳解 2】【gd_shim_module 模塊介紹】

1. 背景 上一章節 我們介紹了 module_t 的 大體框架 &#xff0c;本節內容我們就選擇 我們的 gd_shim_module 模塊為例子&#xff0c;具體剖析一下&#xff0c;它里面的邏輯。 static const char GD_SHIM_MODULE[] "gd_shim_module";// system/main/shim/shim.cc …

【包管理器】主流包管理器_對比_應用場景

不定期更新&#xff0c;建議關注收藏點贊。 鏈接&#xff1a; npm專題 目錄 主流包管理器簡介對比 主流包管理器簡介 主流的包管理器其實有不少&#xff0c;不同語言和平臺都有各自的一套系統。 前端&#xff08;JavaScript/TypeScript&#xff09; 名稱簡介開發者特點npmNo…

參照Spring Boot后端框架實現序列化工具類

本文參照Jackson實現序列化工具類&#xff0c;旨在于簡化開發 JacksonUtil.class public class JacksonUtil {private JacksonUtil() {}/*** 單例*/private final static ObjectMapper OBJECT_MAPPER;static {OBJECT_MAPPER new ObjectMapper();}private static ObjectMappe…

Rust入門之迭代器(Iterators)

Rust入門之迭代器&#xff08;Iterators&#xff09; 本文已同步本人博客網站 本文相關源碼已上傳Github 前言 迭代器&#xff08;Iterators&#xff09;是 Rust 中最核心的工具之一&#xff0c;它不僅是遍歷集合的抽象&#xff0c;更是 Rust 零成本抽象&#xff08;Zero-Co…

若依框架二次開發——RuoYi-AI 本地部署流程

文章目錄 項目環境安裝后端1. 下載項目2. 使用 IDEA 導入項目3. 配置 Maven4. 配置 Maven settings.xml5. 初始化數據庫6. 啟動 Redis7. 修改數據庫配置8. 啟動后端服務安裝管理端1. 下載管理端項目2. 安裝依賴3. 啟動管理端4. 修改管理端配置安裝用戶端1. 下載用戶端項目2. 安…

精品推薦-最新大模型MCP核心架構及最佳實踐資料合集(18份).zip

精品推薦-最新大模型MCP核心架構及最佳實踐資料合集&#xff0c;共18份。 1、2025年程序員必學技能&#xff1a;大模型MCP核心技術.pdf 2、MCP 架構設計剖析&#xff1a;從 Service Mesh 演進到 Agentic Mesh.pdf 3、MCP 架構設計深度剖析&#xff1a;使用 Spring AI MCP 四步…

DataWorks智能體Agent發布!基于MCP實現數據開發與治理自動化運行

在傳統的數據開發工作中&#xff0c;企業用戶或者開發者常常需要進行繁瑣的配置、復雜的代碼撰寫、反復的性能調優和大量重復性的操作&#xff0c;才能實現數據開發、數據集成和數據治理等工作&#xff0c;效率十分低下。 近日&#xff0c;阿里云大數據開發治理平臺DataWorks基…

IDEA 中右側沒有顯示Maven

IDEA 中右側沒有顯示Maven 1. 檢查 Maven 項目是否正確加載 現象 ? 項目是 Maven 項目&#xff0c;但右側沒有 Maven 工具窗口。 ? 項目根目錄下有 pom.xml&#xff0c;但 IDEA 沒有識別為 Maven 項目。 解決方法 手動重新加載 Maven 項目&#xff1a; ? 在 IDEA 中&…

羅技K860鍵盤

羅技藍牙鍵盤的頂部功能鍵F1-F12的原本功能 單擊羅技鍵盤的功能鍵時&#xff0c;默認響應的是鍵盤上面顯示的快進、調節音量等功能。改變回F1~F12原本功能&#xff0c;同時按下 fn和esc組合鍵