Can't solve linker error in building S-Function Builder
54 ビュー (過去 30 日間)
古いコメントを表示
I got this kind of model with S-Function Builder as shown in this image.

But When I build it, I got this error.
#'smex_builder.cpp'
was created successfully
###'smex_builder_wrapper.cpp'
was created successfully
###'smex_builder.tlc'
was created successfully
????? smex_builder.lib ??????? smex_builder.exp ???? smex_builder_wrapper.obj : error LNK2019: ?????????? OrtGetApiBase ??? "void __cdecl `dynamic initializer for 'public: static struct OrtApi const * const Ort::Global::api_''(void)" (??__E?api_@?$Global@X@Ort@@2PEBUOrtApi@@EB@@YAXXZ) ???????? smex_builder.mexw64 : fatal error LNK1120: 1 ??????????
Also, I set parameter tab and library tab like this.
[Port and parameter] tab

[library] tab

I run " mex -setup C++" command and it shows Visual Studio 2022.
I use attached ONNX model as zip file.(out_modified_empty_model.onnx)
Structure of my onnx is like this.

Do you happen to know the solution?
I'm not sure about why this error... I'd be happy if you could give me any advice.
For your information,
I tried this C++ code in S-Function Builder Editor, but I can not figure out what is the cause and where I am missing.
#include "mex.h"
#include <math.h>
#include <onnxruntime_cxx_api.h>
#include <vector>
#include <memory>
extern std::unique_ptrOrt::Env g_env;
extern std::unique_ptrOrt::Session g_session;
extern std::vector<const char> g_input_node_names;
extern std::vector<const char*> g_output_node_names;
void smex_builder_Start_wrapper(void)
{
try {
g_env = std::make_uniqueOrt::Env(ORT_LOGGING_LEVEL_WARNING, "test");
Ort::SessionOptions session_options;
session_options.SetIntraOpNumThreads(1);
session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);
const wchar_t model_path = L"out_modified_empty_model.onnx";
g_session = std::make_uniqueOrt::Session(g_env, model_path, session_options);
Ort::AllocatorWithDefaultOptions allocator;
size_t num_input_nodes = g_session->GetInputCount();
g_input_node_names.resize(num_input_nodes);
for (size_t i = 0; i < num_input_nodes; i++) {
auto input_name = g_session->GetInputNameAllocated(i, allocator);
g_input_node_names[i] = input_name.get();
}
size_t num_output_nodes = g_session->GetOutputCount();
g_output_node_names.resize(num_output_nodes);
for (size_t i = 0; i < num_output_nodes; i++) {
auto output_name = g_session->GetOutputNameAllocated(i, allocator);
g_output_node_names[i] = output_name.get();
}
}
catch (const Ort::Exception& ex) {
mexErrMsgIdAndTxt("myOnnxSfunc:InitError", "初期化エラー: %s", ex.what());
}
}
void smex_builder_Outputs_wrapper(const real_T *u0,
const real_T *u1,
const real_T *u2,
const real_T *u3,
const real_T *u4,
const real_T *u5,
const real_T *u6,
real_T *y0,
real_T y1)
{
mexErrMsgIdAndTxt("mySfunc:TestError", "mexErrMsgIdAndTxt のテストエラー");
try {
std::vector<float> input_data(7);
input_data[0] = static_cast<float>(*u0);
input_data[1] = static_cast<float>(*u1);
input_data[2] = static_cast<float>(*u2);
input_data[3] = static_cast<float>(*u3);
input_data[4] = static_cast<float>(u4);
input_data[5] = static_cast<float>(u5);
input_data[6] = static_cast<float>(u6);
std::vector<int64_t> input_shape = { 1, 7 };
Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
Ort::Value input_tensor = Ort::Value::CreateTensor<float>(
memory_info,
input_data.data(),
input_data.size(),
input_shape.data(),
input_shape.size()
);
auto output_tensors = g_session->Run(
Ort::RunOptions{ nullptr },
g_input_node_names.data(),
&input_tensor,
1,
g_output_node_names.data(),
g_output_node_names.size()
);
// Assuming your model outputs two tensors.
if (output_tensors.size() != 2) {
mexErrMsgIdAndTxt("myOnnxSfunc:OutputError",
"モデルは2つのテンソルを出力する必要があります。");
}
// Check the shape of the first output tensor.
float output_data0 = output_tensors[0].GetTensorMutableData<float>();
auto type_info0 = output_tensors[0].GetTensorTypeAndShapeInfo();
auto output_shape0 = type_info0.GetShape();
if (output_shape0.size() != 2 || output_shape0[0] != 1 || output_shape0[1] != 1) {
mexErrMsgIdAndTxt("myOnnxSfunc:OutputError",
"出力テンソル0の形状が不正です。期待される形状: (1, 1)");
}
// Check the shape of the second output tensor.
float output_data1 = output_tensors[1].GetTensorMutableData<float>();
auto type_info1 = output_tensors[1].GetTensorTypeAndShapeInfo();
auto output_shape1 = type_info1.GetShape();
if (output_shape1.size() != 2 || output_shape1[0] != 1 || output_shape1[1] != 1) {
mexErrMsgIdAndTxt("myOnnxSfunc:OutputError",
"出力テンソル1の形状が不正です。期待される形状: (1, 1)");
}
// Simulink出力ポートへの書き込み
y0[0] = static_cast<double>(output_data0[0]); // y0 に最初の出力
y1[0] = static_cast<double>(output_data1[0]); // y1 に2番目の出力
}
catch (const Ort::Exception& ex) {
mexErrMsgIdAndTxt("myOnnxSfunc:RuntimeError", "実行時エラー: %s", ex.what());
}
}
void smex_builder_Terminate_wrapper(void)
{
g_session.reset();
g_env.reset();
g_input_node_names.clear();
g_output_node_names.clear();
}
0 件のコメント
回答 (1 件)
埃博拉酱
2025 年 1 月 27 日 1:32
What is <onnxruntime_cxx_api.h> and is it provided by MATLAB or a third-party library?
If it's a third-party library, the link error is usually because you didn't link to the lib static library provided by the third party. You'll need to look for the presence of onnxruntime-related lib files, and then add #pragma comment(lib,"onnxruntime_related_lib_file_path") to your code to include the static library in the link.
11 件のコメント
埃博拉酱
2025 年 1 月 29 日 23:26
It's also a good way to comment out some code as you did to exclude unrelated considerations. You may continue to comment out more lines (even all lines except for those required for successful compilation) until something different happens. Pure revision is often of little help.
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!