I got an error when i run build order
Build.bat -target="EcmosimulationEditor Win64 Development" "E:\UE\XXX.uproject" -waitmutex
---
[3/4] Link [x64] UnrealEditor-ECMOSimulation.dll
正在创建库 E:\UE\Intermediate\Build\Win64\x64\UnrealEditor\Development\ECMOSimulation\UnrealEditor-ECMOSimulation.sup.lib 和对象 E:\UE\Intermediate\Build\Win64\x64\UnrealEditor\Development\ECMOSimulation\UnrealEditor-ECMOSimulation.sup.exp
10>NNEModelActor.gen.cpp.obj: Error LNK2019 : 无法解析的外部符号 OrtGetApiBase,函数 "void __cdecl `dynamic initializer for 'public: static struct OrtApi const * const Ort::Global<void>::api_''(void)" (??__E?api_@?$Global@X@Ort@@2PEBUOrtApi@@EB@@YAXXZ) 中引用了该符号
10>NNEModelActor.cpp.obj: Error LNK2001 : 无法解析的外部符号 OrtGetApiBase
10>UnrealEditor-ECMOSimulation.dll: Error LNK1120 : 1 个无法解析的外部命令
Total time in Parallel executor: 2.52 seconds
Total execution time: 3.67 seconds
10>Microsoft.MakeFile.Targets(44,5): Error MSB3073 : 命令“C:\sdk\UE_5.3\Engine\Build\BatchFiles\Build.bat ECMOSimulationEditor Win64 Development -Project="E:\UE\ECMOSimulation.uproject" -WaitMutex -FromMsBuild”已退出,代码为 6。
Here is my code in cpp and .h
NEEModelActor.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "NNEModelData.h"
#include "NNERuntimeORTCpu.h"
#include "UObject/WeakInterfacePtr.h"
#include "NNEModelActor.generated.h"
UCLASS()
class ECMOSIMULATION_API ANNEModelActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ANNEModelActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere)
TObjectPtr<UNNEModelData> PreLoadedModelData;
UPROPERTY(EditAnywhere)
TSoftObjectPtr<UNNEModelData> LazyLoadedModelData;
UFUNCTION(BlueprintCallable, Category = "NNE")
void LoadModel();
UFUNCTION(BlueprintCallable, Category = "NNE")
void CreateModelInstance();
UFUNCTION(BlueprintCallable, Category = "NNE")
void PrepareInputOutput();
UFUNCTION(BlueprintCallable, Category = "NNE")
void RunModel();
private:
TWeakInterfacePtr<INNERuntimeCPU> Runtime;
TUniquePtr<UE::NNE::IModelCPU> Model;
TUniquePtr<UE::NNE::IModelInstanceCPU> ModelInstance;
//Input and output
TArray<float> InputData;
TArray<float> OutputData;
TArray<UE::NNE::FTensorBindingCPU> InputBindings;
TArray<UE::NNE::FTensorBindingCPU> OutputBindings;
};
NNEModelActor.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "NNEModelActor.h"
#include "NNEModelData.h"
#include "NNERuntimeORTCpu.h"
#include "Engine/AssetManager.h"
//#include "Engine/AssetManager.h"
//#include "Interfaces/INNERuntimeCPU.h"
//#include "Interfaces/IModelCPU.h"
//#include "Interfaces/IModelInstanceCPU.h"
// Sets default values
ANNEModelActor::ANNEModelActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ANNEModelActor::BeginPlay()
{
Super::BeginPlay();
LoadModel();
CreateModelInstance();
PrepareInputOutput();
RunModel();
}
// Called every frame
void ANNEModelActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ANNEModelActor::LoadModel()
{
if (PreLoadedModelData)
{
Model = Runtime->CreateModel(PreLoadedModelData);
}
else if (LazyLoadedModelData.IsValid())
{
UAssetManager::GetStreamableManager().RequestAsyncLoad(LazyLoadedModelData.ToSoftObjectPath());
}
if (!Model)
{
UE_LOG(LogTemp, Error, TEXT("Failed to load the model"));
return;
}
}
void ANNEModelActor::CreateModelInstance()
{
if (Model.IsValid())
{
ModelInstance = Model->CreateModelInstance();
if (ModelInstance.IsValid())
{
UE_LOG(LogTemp, Log, TEXT("Model instance created successfully"));
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to create the model instance"));
}
}
}
void ANNEModelActor::PrepareInputOutput()
{
if (ModelInstance.IsValid())
{
// Get input tensor descriptions
TConstArrayView<UE::NNE::FTensorDesc> InputTensorDescs = ModelInstance->GetInputTensorDescs();
checkf(InputTensorDescs.Num() == 1, TEXT("The current example supports only models with a single input tensor"));
// Get input tensor shape and ensure it is concrete
UE::NNE::FSymbolicTensorShape SymbolicInputTensorShape = InputTensorDescs[0].GetShape();
checkf(SymbolicInputTensorShape.IsConcrete(), TEXT("The current example supports only models without variable input tensor dimensions"));
TArray<UE::NNE::FTensorShape> InputTensorShapes = { UE::NNE::FTensorShape::MakeFromSymbolic(SymbolicInputTensorShape) };
// Set input tensor shapes
ModelInstance->SetInputTensorShapes(InputTensorShapes);
// Get output tensor descriptions
TConstArrayView<UE::NNE::FTensorDesc> OutputTensorDescs = ModelInstance->GetOutputTensorDescs();
checkf(OutputTensorDescs.Num() == 1, TEXT("The current example supports only models with a single output tensor"));
// Get output tensor shape and ensure it is concrete
UE::NNE::FSymbolicTensorShape SymbolicOutputTensorShape = OutputTensorDescs[0].GetShape();
checkf(SymbolicOutputTensorShape.IsConcrete(), TEXT("The current example supports only models without variable output tensor dimensions"));
TArray<UE::NNE::FTensorShape> OutputTensorShapes = { UE::NNE::FTensorShape::MakeFromSymbolic(SymbolicOutputTensorShape) };
// Allocate memory for input and output data
InputData.SetNumZeroed(InputTensorShapes[0].Volume());
InputBindings.SetNumZeroed(1);
InputBindings[0].Data = InputData.GetData();
InputBindings[0].SizeInBytes = InputData.Num() * sizeof(float);
OutputData.SetNumZeroed(OutputTensorShapes[0].Volume());
OutputBindings.SetNumZeroed(1);
OutputBindings[0].Data = OutputData.GetData();
OutputBindings[0].SizeInBytes = OutputData.Num() * sizeof(float);
}
else
{
UE_LOG(LogTemp, Error, TEXT("ModelInstance is not valid"));
}
}
void ANNEModelActor::RunModel()
{
if (ModelInstance)
{
if (ModelInstance->RunSync(InputBindings, OutputBindings) != 0)
{
UE_LOG(LogTemp, Error, TEXT("Failed to run the model"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("Model inference completed"));
// Log or process OutputData as needed
for (float Value : OutputData)
{
UE_LOG(LogTemp, Log, TEXT("Output Value: %f"), Value);
}
}
}
else
{
UE_LOG(LogTemp, Error, TEXT("Model instance is not valid"));
}
}
Thank you for helping me.