#include "ANSLIB.h" #include "ANSLibsLoader.h" #include #include #define LOAD_FUNC(name) \ name##Func = (name##FuncT)GetProcAddress(dllHandle, #name); \ if (!name##Func) { success = false; } namespace ANSCENTER { namespace { // Function-pointer typedefs for the ANSLicensingSystem C-facade exports. // Resolved exactly once during PreloadSharedDllsOnce(); after that the // pointers are write-once globals — concurrent reads are race-free. using ANSLogger_LogFnT = void(*)(const char*, const char*, const char*, int); using ANSCENTER_IsDbgEnFnT = int (*)(void); using ANSCENTER_DebugLogFnT = void(*)(const char*); ANSLogger_LogFnT g_ANSLogger_LogInfo = nullptr; ANSLogger_LogFnT g_ANSLogger_LogError = nullptr; ANSLogger_LogFnT g_ANSLogger_LogFatal = nullptr; ANSCENTER_IsDbgEnFnT g_ANSCENTER_IsDebugViewEnabled = nullptr; ANSCENTER_DebugLogFnT g_ANSCENTER_DebugLog = nullptr; // Pre-load all ANSCORE DLLs from the Shared folder using full paths. // This ensures the correct versions are loaded regardless of PATH order // (e.g., DLHUB_Runtime_Engine may contain older copies on some machines). // Run exactly once per process so LoadLibrary refcounts don't grow per // ANSLIB instance. The DLLs are intentionally pinned for process lifetime. void PreloadSharedDllsOnce() { static std::once_flag s_preloadFlag; std::call_once(s_preloadFlag, []() { const char* sharedDir = "C:\\ProgramData\\ANSCENTER\\Shared\\"; const char* preloadDlls[] = { "ANSLicensingSystem.dll", "anslicensing.dll", "ANSMOT.dll", "ANSODEngine.dll", nullptr }; for (int i = 0; preloadDlls[i] != nullptr; i++) { std::string fullPath = std::string(sharedDir) + preloadDlls[i]; LoadLibraryA(fullPath.c_str()); } // Ensure all shared DLLs (OpenCV, OpenVINO, TRT, ORT) are pre-loaded ANSCENTER::ANSLibsLoader::Initialize(); // Resolve logging C-facade symbols from the (now-pinned) licensing DLL. // Use GetModuleHandleA — the DLL is already in this process's module // list courtesy of the LoadLibraryA above, so refcount is unchanged. if (HMODULE lic = GetModuleHandleA("ANSLicensingSystem.dll")) { g_ANSLogger_LogInfo = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogInfo"); g_ANSLogger_LogError = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogError"); g_ANSLogger_LogFatal = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogFatal"); g_ANSCENTER_IsDebugViewEnabled = (ANSCENTER_IsDbgEnFnT) GetProcAddress(lic, "ANSCENTER_IsDebugViewEnabled"); g_ANSCENTER_DebugLog = (ANSCENTER_DebugLogFnT)GetProcAddress(lic, "ANSCENTER_DebugLog"); } }); } } ANSLIB::ANSLIB() { PreloadSharedDllsOnce(); const char* dllPath = "C:\\ProgramData\\ANSCENTER\\Shared\\ANSODEngine.dll"; dllHandle = LoadLibraryA(dllPath); if (!dllHandle) { return; } bool success = true; LOAD_FUNC(CreateANSODHandle_CS); LOAD_FUNC(RunInference_CPP); LOAD_FUNC(RunInferenceComplete_CPP); LOAD_FUNC(OptimizeModelStr_CS); LOAD_FUNC(GetEngineType); LOAD_FUNC(LoadModelFromFolder); LOAD_FUNC(GetActiveRect); LOAD_FUNC(DetectMovement); LOAD_FUNC(Optimize); LOAD_FUNC(GetODParameters); LOAD_FUNC(ReleaseANSODHandle); LOAD_FUNC(UpdateDetectionMinScore); LOAD_FUNC(SetPrompt); LOAD_FUNC(SetTracker); LOAD_FUNC(SetTrackerParameters); loaded = success; if (!loaded) { FreeLibrary(dllHandle); dllHandle = nullptr; } } ANSLIB* ANSLIB::Create() { try { auto ptr = std::make_unique(); return ptr.release(); } catch (...) { return nullptr; } } void ANSLIB::Destroy(ANSLIB* instance) { std::unique_ptr ptr(instance); } ANSLIB::~ANSLIB() noexcept { try { if (ANSHandle && ReleaseANSODHandleFunc) { ReleaseANSODHandleFunc(&ANSHandle); ANSHandle = nullptr; } if (dllHandle) { FreeLibrary(dllHandle); dllHandle = nullptr; } } catch (...) {} } bool ANSLIB::IsLoaded() const { return loaded; } // Public APIs int ANSLIB::Initialize(const char* licenseKey, const char* modelFilePath, const char* modelFileZipPassword, float modelThreshold, float modelConfThreshold, float modelNMSThreshold, int modelType, int detectionType, int loadEngineOnCreation,std::string& labels) { if (!loaded) { return -1; } if (CreateANSODHandle_CSFunc) { if (ANSHandle && ReleaseANSODHandleFunc) { ReleaseANSODHandleFunc(&ANSHandle); ANSHandle = nullptr; } const char* result = CreateANSODHandle_CSFunc(&ANSHandle, licenseKey, modelFilePath, modelFileZipPassword, modelThreshold, modelConfThreshold, modelNMSThreshold, 1, modelType, detectionType, loadEngineOnCreation); labels = (result != nullptr) ? std::string(result) : std::string(); if (labels.empty()) { return -1; } else { return 1; } } return 0; } int ANSLIB::RunInference(cv::Mat cvImage, const char* cameraId, std::vector& detectionResult) { if (!loaded) { return -1; } if (RunInference_CPPFunc) { try { cv::Mat* rawPtr = &cvImage; int result = RunInference_CPPFunc(&ANSHandle, &rawPtr, cameraId, detectionResult); return result; } catch (...) { return -1; } } return -1; } int ANSLIB::RunInferenceWithOptions(cv::Mat cvImage, const char* cameraId, const char* activeROIMode, std::vector& detectionResult) { if (!loaded) { return -1; } if (RunInferenceComplete_CPPFunc) { try { cv::Mat* rawPtr = &cvImage; int result = RunInferenceComplete_CPPFunc(&ANSHandle, &rawPtr, cameraId, activeROIMode,detectionResult); return result; } catch (...) { return -1; } } return -1; } int ANSLIB::OptimizeModel(const char* modelFilePath, const char* modelFileZipPassword, int modelType, int modelDetectionType,int fp16) { if (!loaded) { return -1; } if (OptimizeModelStr_CSFunc) { const char* result = OptimizeModelStr_CSFunc(modelFilePath, modelFileZipPassword, modelType, modelDetectionType, fp16); if (result) { return 1; } else { return -1; } } return -1; } const char* ANSLIB::CreateANSODHandle_CS(void** Handle, const char* licenseKey, const char* modelFilePath, const char* modelFileZipPassword, float modelThreshold, float modelConfThreshold, float modelNMSThreshold, int autoDetectEngine, int modelType, int detectionType, int loadEngineOnCreation) { return CreateANSODHandle_CSFunc ? CreateANSODHandle_CSFunc(Handle, licenseKey, modelFilePath, modelFileZipPassword, modelThreshold, modelConfThreshold, modelNMSThreshold, autoDetectEngine, modelType, detectionType, loadEngineOnCreation) : "Function not loaded"; } const char* ANSLIB::OptimizeModelStr_CS(const char* modelFilePath, const char* modelFileZipPassword, int modelType, int modelDetectionType,int fp16) { return OptimizeModelStr_CSFunc ? OptimizeModelStr_CSFunc(modelFilePath, modelFileZipPassword, modelType, modelDetectionType,fp16) : "Function not loaded"; } int ANSLIB::RunInference_CPP(void** Handle, cv::Mat** cvImage, const char* cameraId, std::vector& detectionResult) { return RunInference_CPPFunc ? RunInference_CPPFunc(Handle, cvImage, cameraId, detectionResult) : -1; } int ANSLIB::RunInferenceComplete_CPP(void** Handle, cv::Mat** cvImage, const char* cameraId, const char* activeROIMode, std::vector& detectionResult) { return RunInferenceComplete_CPPFunc ? RunInferenceComplete_CPPFunc(Handle, cvImage, cameraId, activeROIMode, detectionResult) : -1; } int ANSLIB::GetEngineType() { if (!loaded || !GetEngineTypeFunc) return -1; return GetEngineTypeFunc(); } int ANSLIB::LoadModelFromFolder(const char* licenseKey, const char* modelName, const char* className, float detectionScoreThreshold, float modelConfThreshold, float modelMNSThreshold, int autoDetectEngine, int modelType, int detectionType, int loadEngineOnCreation, const char* modelFolder,std::string& labelMap) { if (!loaded || !LoadModelFromFolderFunc) return -1; if (ANSHandle && ReleaseANSODHandleFunc) { ReleaseANSODHandleFunc(&ANSHandle); ANSHandle = nullptr; } return LoadModelFromFolderFunc(&ANSHandle, licenseKey, modelName, className, detectionScoreThreshold, modelConfThreshold, modelMNSThreshold, autoDetectEngine, modelType, detectionType, loadEngineOnCreation,modelFolder, labelMap); } int ANSLIB::GetActiveRect(cv::Mat cvImage, cv::Rect& activeWindow) { if (!loaded || !GetActiveRectFunc) return -1; return GetActiveRectFunc(&ANSHandle, cvImage, activeWindow); } int ANSLIB::DetectMovement(cv::Mat image, const char* cameraId, std::vector& results) { if (!loaded || !DetectMovementFunc) return -1; return DetectMovementFunc(&ANSHandle, image, cameraId, results); } int ANSLIB::ReleaseANSODHandle(void** Handle) { return ReleaseANSODHandleFunc ? ReleaseANSODHandleFunc(Handle) : -1; } cv::Rect ANSLIB::GetActiveWindow(cv::Mat cvImage) { cv::Rect activeWindow; if (GetActiveRect(cvImage, activeWindow) == 0) { return activeWindow; } return cv::Rect(); // Return an empty rectangle if failed } int ANSLIB::GetODParameters(ANSCENTER::Params& param) { if (!loaded || !GetODParametersFunc) return -1; return GetODParametersFunc(&ANSHandle, param); } int ANSLIB::Optimize(bool fp16) { if (!loaded || !OptimizeFunc) return -1; return OptimizeFunc(&ANSHandle, fp16); } int ANSLIB::UpdateDetectionMinScore(float scoreThreshold) { if (!loaded || !UpdateDetectionMinScoreFunc) return -1; return UpdateDetectionMinScoreFunc(&ANSHandle, scoreThreshold); } int ANSLIB::SetPrompt(const char* text) { if (!loaded || !SetPromptFunc) return -1; return SetPromptFunc(&ANSHandle, text); } int ANSLIB::SetTracker(int trackerType, int enableTracker) { if (!loaded || !SetTrackerFunc) return -1; return SetTrackerFunc(&ANSHandle, trackerType, enableTracker); } int ANSLIB::SetTrackerParameters(const char* trackerParams) { if (!loaded || !SetTrackerParametersFunc) return -1; return SetTrackerParametersFunc(&ANSHandle, trackerParams); } // ------------------------------------------------------------------------ // Static logging API. Each call ensures the DLL/symbols are resolved (cheap // after the first call — std::call_once degenerates to an atomic load) then // forwards to the C facade. Null-pointer guard makes missing symbols a // silent no-op rather than a crash. // ------------------------------------------------------------------------ int ANSLIB::IsDebugViewEnabled() { PreloadSharedDllsOnce(); return g_ANSCENTER_IsDebugViewEnabled ? g_ANSCENTER_IsDebugViewEnabled() : 0; } void ANSLIB::DebugLog(const char* preformattedLine) { PreloadSharedDllsOnce(); if (!preformattedLine) return; if (g_ANSCENTER_DebugLog) { // Preferred path: licensing DLL applies the prefix scrubber and emits. g_ANSCENTER_DebugLog(preformattedLine); return; } // Fallback for environments where ANSLicensingSystem.dll is missing: // emit raw to DebugView + stderr without filtering. Better than dropping. OutputDebugStringA(preformattedLine); std::fputs(preformattedLine, stderr); std::fflush(stderr); } void ANSLIB::LogInfo(const char* src, const char* msg, const char* file, int line) { PreloadSharedDllsOnce(); if (g_ANSLogger_LogInfo) g_ANSLogger_LogInfo(src, msg, file, line); } void ANSLIB::LogError(const char* src, const char* msg, const char* file, int line) { PreloadSharedDllsOnce(); if (g_ANSLogger_LogError) g_ANSLogger_LogError(src, msg, file, line); } void ANSLIB::LogFatal(const char* src, const char* msg, const char* file, int line) { PreloadSharedDllsOnce(); if (g_ANSLogger_LogFatal) g_ANSLogger_LogFatal(src, msg, file, line); } }