ONNX RuntimeC++ 静态库下载安装和使用教程

onnxruntime官方已经提供动态库的GPU和CPU版本各个操作系统支持版本,但是没有静态库版本。这个教程主要是讲解静态库版本下载安装和使用教程,首先讲解之间的区别

静态库 vs 动态库区别

静态库

  • 文件扩展名 : .lib (Windows), .a (Linux/macOS)
  • 链接方式: 编译时链接,代码被复制到最终可执行文件中
  • 部署: 单个可执行文件,无需额外DLL
  • 大小: 可执行文件较大
  • 兼容性: 更好,不依赖系统环境

动态库

  • 文件扩展名 : .dll (Windows), .so (Linux), .dylib (macOS)
  • 链接方式: 运行时加载,多个程序可共享
  • 部署: 需要分发DLL文件
  • 大小: 可执行文件较小
  • 内存使用: 更高效(共享库)

ONNX Runtime 静态库使用教程

1. 环境准备

下载ONNX Runtime

官方GitHub下载预编译包或自行编译。

目录结构:

复制代码
onnxruntime/
├── include/
├── lib/
│   ├── onnxruntime.lib (静态库)
│   └── onnxruntime.dll (动态库)
└── bin/

2. CMake 配置示例

cmake 复制代码
cmake_minimum_required(VERSION 3.18)
project(ONNXRuntimeDemo)

set(CMAKE_CXX_STANDARD 14)

# 设置ONNX Runtime路径
set(ONNXRUNTIME_ROOT "path/to/onnxruntime")

# 包含目录
include_directories(${ONNXRUNTIME_ROOT}/include)

# 静态库链接
if(WIN32)
    # Windows 静态库配置
    set(ONNXRUNTIME_LIB ${ONNXRUNTIME_ROOT}/lib/onnxruntime.lib)
    
    # 需要的一些系统库
    set(SYSTEM_LIBS 
        ws2_32
        advapi32
        dbghelp
    )
else()
    # Linux/macOS 静态库配置
    set(ONNXRUNTIME_LIB ${ONNXRUNTIME_ROOT}/lib/libonnxruntime.a)
    
    # 需要的系统库
    set(SYSTEM_LIBS
        pthread
        dl
    )
endif()

# 创建可执行文件
add_executable(onnx_demo main.cpp)

# 链接库
target_link_libraries(onnx_demo 
    ${ONNXRUNTIME_LIB}
    ${SYSTEM_LIBS}
)

3. C++ 代码示例

cpp 复制代码
#include <onnxruntime_cxx_api.h>
#include <iostream>
#include <vector>
#include <chrono>

class ONNXModel {
private:
    Ort::Env env;
    Ort::Session session;
    std::vector<const char*> input_names;
    std::vector<const char*> output_names;

public:
    ONNXModel(const std::string& model_path, int device_id = 0) 
        : env(ORT_LOGGING_LEVEL_WARNING, "ONNXModel") {
        
        // 会话选项
        Ort::SessionOptions session_options;
        
        // 设置线程数
        session_options.SetIntraOpNumThreads(1);
        session_options.SetInterOpNumThreads(1);
        
        // 对于GPU使用,取消注释下面几行
        // OrtCUDAProviderOptions cuda_options;
        // cuda_options.device_id = device_id;
        // session_options.AppendExecutionProvider_CUDA(cuda_options);
        
        // 创建会话
        session = Ort::Session(env, model_path.c_str(), session_options);
        
        // 获取输入输出信息
        setup_io_names();
    }
    
private:
    void setup_io_names() {
        Ort::AllocatorWithDefaultOptions allocator;
        
        // 输入名称
        size_t num_input_nodes = session.GetInputCount();
        for(size_t i = 0; i < num_input_nodes; i++) {
            char* input_name = session.GetInputName(i, allocator);
            input_names.push_back(input_name);
        }
        
        // 输出名称
        size_t num_output_nodes = session.GetOutputCount();
        for(size_t i = 0; i < num_output_nodes; i++) {
            char* output_name = session.GetOutputName(i, allocator);
            output_names.push_back(output_name);
        }
    }
    
public:
    std::vector<float> inference(const std::vector<float>& input_data, 
                                const std::vector<int64_t>& input_shape) {
        
        Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(
            OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault);
        
        // 创建输入tensor
        auto input_tensor = Ort::Value::CreateTensor<float>(
            memory_info, 
            const_cast<float*>(input_data.data()), 
            input_data.size(),
            input_shape.data(), 
            input_shape.size()
        );
        
        // 运行推理
        auto output_tensors = session.Run(
            Ort::RunOptions{nullptr}, 
            input_names.data(), 
            &input_tensor, 
            input_names.size(),
            output_names.data(), 
            output_names.size()
        );
        
        // 获取输出
        float* floatarr = output_tensors[0].GetTensorMutableData<float>();
        auto tensor_shape = output_tensors[0].GetTensorTypeAndShapeInfo().GetShape();
        
        size_t output_size = 1;
        for(auto dim : tensor_shape) {
            output_size *= dim;
        }
        
        return std::vector<float>(floatarr, floatarr + output_size);
    }
    
    void print_model_info() {
        Ort::AllocatorWithDefaultOptions allocator;
        
        std::cout << "=== Model Information ===" << std::endl;
        
        // 输入信息
        std::cout << "Inputs:" << std::endl;
        size_t num_inputs = session.GetInputCount();
        for(size_t i = 0; i < num_inputs; i++) {
            auto type_info = session.GetInputTypeInfo(i);
            auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
            auto shape = tensor_info.GetShape();
            
            char* name = session.GetInputName(i, allocator);
            std::cout << "  " << i << ": " << name << " Shape: [";
            for(size_t j = 0; j < shape.size(); j++) {
                std::cout << shape[j];
                if(j < shape.size() - 1) std::cout << ", ";
            }
            std::cout << "]" << std::endl;
        }
        
        // 输出信息
        std::cout << "Outputs:" << std::endl;
        size_t num_outputs = session.GetOutputCount();
        for(size_t i = 0; i < num_outputs; i++) {
            auto type_info = session.GetOutputTypeInfo(i);
            auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
            auto shape = tensor_info.GetShape();
            
            char* name = session.GetOutputName(i, allocator);
            std::cout << "  " << i << ": " << name << " Shape: [";
            for(size_t j = 0; j < shape.size(); j++) {
                std::cout << shape[j];
                if(j < shape.size() - 1) std::cout << ", ";
            }
            std::cout << "]" << std::endl;
        }
    }
};

// 示例使用
int main() {
    try {
        // 初始化模型
        ONNXModel model("model.onnx");
        
        // 打印模型信息
        model.print_model_info();
        
        // 准备输入数据 (示例)
        std::vector<float> input_data(1 * 3 * 224 * 224, 0.5f); // 假设是图像分类模型
        std::vector<int64_t> input_shape = {1, 3, 224, 224};
        
        // 执行推理
        auto start_time = std::chrono::high_resolution_clock::now();
        
        auto output = model.inference(input_data, input_shape);
        
        auto end_time = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
        
        std::cout << "Inference time: " << duration.count() << " ms" << std::endl;
        
        // 输出结果
        std::cout << "Output size: " << output.size() << std::endl;
        std::cout << "First 10 values: ";
        for(int i = 0; i < 10 && i < output.size(); i++) {
            std::cout << output[i] << " ";
        }
        std::cout << std::endl;
        
    } catch(const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return -1;
    }
    
    return 0;
}

4. 编译和运行

Windows (命令行)
bash 复制代码
mkdir build
cd build
cmake -G "Visual Studio 16 2019" ..
cmake --build . --config Release
Linux/macOS
bash 复制代码
mkdir build
cd build
cmake ..
make -j4

5. 高级功能

使用GPU
cpp 复制代码
// 在构造函数中添加GPU支持
#ifdef USE_CUDA
    OrtCUDAProviderOptions cuda_options;
    cuda_options.device_id = device_id;
    session_options.AppendExecutionProvider_CUDA(cuda_options);
#endif
自定义内存分配
cpp 复制代码
class CustomAllocator : public Ort::Allocator {
    // 实现自定义内存分配器
};

注意事项

  1. 静态库大小: ONNX Runtime静态库较大,考虑使用动态库如果对可执行文件大小敏感
  2. 依赖管理: 静态库包含所有依赖,确保没有冲突的系统库版本
  3. 编译时间: 静态链接可能增加编译时间
  4. 内存使用: 每个使用静态库的程序都有独立的ONNX Runtime副本

常见问题

  1. 链接错误: 确保所有必要的系统库都已链接
  2. 版本兼容性: 确保ONNX Runtime版本与模型兼容
  3. 内存泄漏: 使用RAII方式管理Ort对象

这个教程提供了ONNX Runtime静态库的基本使用方法,你可以根据具体需求进行调整和扩展。

关于onnxruntime静态库可以下载版本如下:

版本名称 下载地址
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.23.2 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.23.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.22.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.22.0 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.20.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.20.0 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.19.2 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.19.0 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.18.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.18.0 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.17.3 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.17.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.17.0 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.16.3 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.16.2 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.16.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x64-static-lib-1.16.0 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.23.2 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.23.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.22.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.22.0 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.20.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.19.2 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.19.0 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.18.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.18.0 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.17.3 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.17.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.17.0 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.16.3 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.16.2 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.16.1 点我下载
[C++onnxruntime静态库]onnxruntime-win-x86-static-lib-1.16.0 点我下载
相关推荐
星释1 小时前
Rust 练习册 95:React与响应式编程
开发语言·react.js·rust
Evand J1 小时前
【MATLAB例程】3D雷达-IMU融合定位系统(基于扩展卡尔曼滤波)|雷达观测距离、俯仰角、方向角,IMU包括6维(加速度与角速度)。附下载链接
开发语言·matlab·跟踪·雷达观测·三维定位·ekf滤波
毕设源码柳学姐1 小时前
计算机毕设 java 智慧社区服务系统 SSM 框架社区生活平台 Java 开发的便民服务与互动系统
java·开发语言·生活
誰能久伴不乏1 小时前
Linux文件套接字AF_UNIX
linux·服务器·c语言·c++·unix
陈奕昆1 小时前
n8n实战营Day3:电商订单全流程自动化·需求分析与流程拆解
大数据·开发语言·人工智能·自动化·需求分析·n8n
5***V9331 小时前
MacOS升级ruby版本
开发语言·macos·ruby
星释1 小时前
Rust 练习册 96:Rectangles与几何计算
开发语言·后端·rust
JienDa1 小时前
JienDa聊PHP:电商实战中主流PHP框架的协同策略与架构优化
开发语言·架构·php