C++可直接调用ONNX Runtime实现高性能轻量部署,需严格匹配模型输入输出名称、shape与dtype,正确管理内存并配置执行提供者与优化选项。
可以直接用 C++ 调用 ONNX Runtime 进行模型推理,无需 Python 中转,性能高、部署轻量。关键在于正确加载模型、匹配输入输出张量形状与数据类型,并避免内存生命周期错误。
必须显式设置 Ort::Env 和 Ort::SessionOptions,否则默认行为可能触发调试日志或禁用优化。Windows 下若链接失败,大概率是没正确导入 onnxruntime.lib(不是 DLL)或 ABI 不匹配(如 /MD 与 /MT 混用)。
Ort::Env 建议用 ORT_LOGGING_LEVEL_WARNING 避免刷屏session_options.SetGraphOptimizationLevel(ORT_ENABLE_ALL)
OrtSessionOptionsAppendExecutionProvider_CUDA(options, 0),且必须在 Ort::Session 构造前完成LD_LIBRARY_PATH 包含 libonnxruntime.so 路径ONNX Runtime 不接管用户分配的内存,Ort::Value::CreateTensor 的第 4 个参数(data pointer)必须保证在整个 Run() 调用期间有效。常见崩溃源于栈内存传入或提前 free()。
std::vector 分配输入数据,再用 .data() 传指针{1, 3, 224, 224},不能是 {3, 224, 224}
Ort::Value::CreateTensor 指定 Ort::MemoryInfo::CreateCpu(..., OrtArenaAllocator) 并自行处理 layout(pixel - [123.675, 116.28, 103.53]) / [58.395, 57.12, 57.375],顺序错会导致输出全零session.Run() 返回的是 std::vector<:value>,每个元素对应一个输出节点。直接调用 .GetTensorData 得到指针,但必须先确认输出 shape 和数据类型,否则越界读写。
output_values[0].GetTensorTypeAndShapeInfo().GetShape() 检查维度,比如分类模型常为 {1, 1000}
output_values[0].GetTensorTypeAndShapeInfo().GetElementType() 确认是否为 ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT
"output" —— 查看模型用 netron 或 onnx.shape_inference.infer_shapes() 确认实际 output nameint64(如 token ids),需用 .GetTensorData() ,混用类型会读出垃圾值Ort::Session session(env, L"model.onnx", session_options); std::vectorinput_names = {"input"}; std::vector output_names = {"output"}; std::vector
input_shape = {1, 3, 224, 224}; std::vector input_tensor_values(1 3 224 * 224, 0.0f); // ... 填充 input_tensor_values auto memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAlloc
ator, OrtMemTypeDefault); auto input_tensor = Ort::Value::CreateTensor
( memory_info, input_tensor_values.data(), input_tensor_values.size(), input_shape.data(), input_shape.size()); auto output_tensors = session.Run( Ort::RunOptions{nullptr}, input_names.data(), &input_tensor, 1, output_names.data(), 1 );
float* output_data = output_tensors[0].GetTensorData
(); std::vector output_shape = output_tensors[0].GetTensorTypeAndShapeInfo().GetShape();
最易被忽略的是:模型输入/输出名称、shape、dtype 三者必须与 ONNX 文件定义严格一致,任何一项不匹配都会导致静默错误(如输出全零)或段错误。建议首次部署时用 Python 的 onnxruntime.InferenceSession 同样输入跑一遍,比对输出数值和 shape,再迁移到 C++。