#include "ANSTrainingEngine.h" #include "ANSODTraininingEngine.h" #include "ANSYOLOTrainingEngine.h" #include "ANSYOLOCLTrainingEngine.h" #include "ANSYOLOSEGTrainingEngine.h" #include "ANSYOLOOBBTrainingEngine.h" #include "Utility.h" #include #include #include #include #include #include #include #include #include #include #include #include // DebugView: filter on "[ANSTRE]" — gated by ANSCORE_DEBUGVIEW in ANSLicense.h. // Handle registry with refcount — prevents use-after-free when // ReleaseANSTREHandle is called while an operation is still running. // destructionStarted: set by the first Unregister caller; blocks new Acquires // and makes subsequent Unregister calls return false without deleting. // Prevents double-free when Release is raced on the same handle. struct TREEntry { int refcount; bool destructionStarted; }; static std::unordered_map& TREHandleRegistry() { static std::unordered_map s; return s; } static std::mutex& TREHandleRegistryMutex() { static std::mutex m; return m; } static std::condition_variable& TREHandleRegistryCV() { static std::condition_variable cv; return cv; } static void RegisterTREHandle(ANSCENTER::ANSTRE* h) { std::lock_guard lk(TREHandleRegistryMutex()); TREHandleRegistry()[h] = { 1, false }; ANS_DBG("ANSTRE","Register: handle=%p (uint=%llu) registrySize=%zu", (void*)h, (unsigned long long)(uintptr_t)h, TREHandleRegistry().size()); } static ANSCENTER::ANSTRE* AcquireTREHandle(ANSCENTER::ANSTRE* h) { std::lock_guard lk(TREHandleRegistryMutex()); auto it = TREHandleRegistry().find(h); if (it == TREHandleRegistry().end()) { ANS_DBG("ANSTRE","Acquire FAIL: handle=%p (uint=%llu) NOT in registry. registrySize=%zu", (void*)h, (unsigned long long)(uintptr_t)h, TREHandleRegistry().size()); size_t i = 0; for (auto& kv : TREHandleRegistry()) { ANS_DBG("ANSTRE"," registry[%zu] = %p (uint=%llu) refcount=%d destructionStarted=%d", i++, (void*)kv.first, (unsigned long long)(uintptr_t)kv.first, kv.second.refcount, kv.second.destructionStarted ? 1 : 0); } return nullptr; } if (it->second.destructionStarted) { ANS_DBG("ANSTRE","Acquire FAIL: handle=%p is being destroyed (destructionStarted=true)", (void*)h); return nullptr; } it->second.refcount++; ANS_DBG("ANSTRE","Acquire OK: handle=%p refcount=%d", (void*)h, it->second.refcount); return h; } static bool ReleaseTREHandleRef(ANSCENTER::ANSTRE* h) { std::lock_guard lk(TREHandleRegistryMutex()); auto it = TREHandleRegistry().find(h); if (it == TREHandleRegistry().end()) return false; it->second.refcount--; if (it->second.refcount <= 0) { TREHandleRegistryCV().notify_all(); } return false; // Only Unregister deletes. } static bool UnregisterTREHandle(ANSCENTER::ANSTRE* h) { std::unique_lock lk(TREHandleRegistryMutex()); auto it = TREHandleRegistry().find(h); if (it == TREHandleRegistry().end()) { ANS_DBG("ANSTRE","Unregister: handle=%p NOT in registry (already gone)", (void*)h); return false; } if (it->second.destructionStarted) { ANS_DBG("ANSTRE","Unregister: handle=%p already being destroyed by another thread, returning false", (void*)h); return false; // Another thread already owns the delete. } ANS_DBG("ANSTRE","Unregister: handle=%p starting (refcount before=%d)", (void*)h, it->second.refcount); it->second.destructionStarted = true; it->second.refcount--; bool ok = TREHandleRegistryCV().wait_for(lk, std::chrono::seconds(30), [&]() { auto it2 = TREHandleRegistry().find(h); return it2 == TREHandleRegistry().end() || it2->second.refcount <= 0; }); if (!ok) { ANS_DBG("ANSTRE","WARNING: Unregister timed out waiting for in-flight operations on handle=%p", (void*)h); OutputDebugStringA("WARNING: UnregisterTREHandle timed out waiting for in-flight operations\n"); } TREHandleRegistry().erase(h); return true; } // RAII guard — ensures ReleaseTREHandleRef is always called class TREHandleGuard { ANSCENTER::ANSTRE* engine; public: explicit TREHandleGuard(ANSCENTER::ANSTRE* e) : engine(e) {} ~TREHandleGuard() { if (engine) ReleaseTREHandleRef(engine); } ANSCENTER::ANSTRE* get() const { return engine; } explicit operator bool() const { return engine != nullptr; } TREHandleGuard(const TREHandleGuard&) = delete; TREHandleGuard& operator=(const TREHandleGuard&) = delete; }; template T getData(const boost::property_tree::ptree& pt, const std::string& key) { T ret; if (boost::optional data = pt.get_optional(key)) { ret = data.get(); } return ret; } namespace ANSCENTER { bool ANSTRE::IsProcessRunning(const char* processName){ bool isRunning = false; PROCESSENTRY32 processEntry; processEntry.dwSize = sizeof(PROCESSENTRY32); // Create a snapshot of all running processes HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot == INVALID_HANDLE_VALUE) { // Handle error (e.g., log or return false) return false; } if (Process32First(snapshot, &processEntry)) { do { #ifdef UNICODE // Convert process name to wide string using proper UTF-8 conversion int wideLen = MultiByteToWideChar(CP_UTF8, 0, processName, -1, nullptr, 0); std::wstring wProcessName(wideLen > 0 ? wideLen - 1 : 0, L'\0'); if (wideLen > 0) MultiByteToWideChar(CP_UTF8, 0, processName, -1, &wProcessName[0], wideLen); if (_wcsicmp(processEntry.szExeFile, wProcessName.c_str()) == 0) { #else // Compare the process name with the target process name (case-insensitive) if (_stricmp(processEntry.szExeFile, processName) == 0) { #endif isRunning = true; break; } } while (Process32Next(snapshot, &processEntry)); } CloseHandle(snapshot); return isRunning; } bool ANSTRE::ZipExperiment(std::string projectName, int experimentNumber) { bool zipModelExist = false; _projectName = Space2Underscore(projectName); std::string projectPath = FindFilePathInFileList(_projects, _projectName); if (FolderExist(projectPath)) { std::string experimentPath = projectPath + "\\experiments\\" + std::to_string(experimentNumber); std::string zipExperimentPath = experimentPath + ".zip"; std::string preTrainWeightFile = experimentPath + "\\train_last.pt"; if (FileExist(zipExperimentPath))fs::remove(zipExperimentPath); if (ZipFolderWithPassword(experimentPath.c_str(), zipExperimentPath.c_str(), _zipPassword.c_str())) { DeleteFolder(experimentPath); } return FileExist(zipExperimentPath); } else { this->_logger.LogError("ANYLTRE::ANSTRE::ZipExperimen", "Invalid project path.", __FILE__, __LINE__); return false; } } double ANSTRE::ParseObjectDetectionMAP(std::string stEvaluationResult) { std::regex valuePattern("all\\s+\\d+\\s+\\d+\\s+\\d\\.\\d+\\s+\\d\\.\\d+\\s+\\d\\.\\d+\\s+(\\d\\.\\d+)"); std::smatch matches; if (std::regex_search(stEvaluationResult, matches, valuePattern) && matches.size() > 1) { return std::atof(matches[1].str().c_str()); } else { return 0; } } std::string ANSTRE::GetLatestValidFolderAndDeleteOthers(const std::string& projectName, const std::string& rootPath) { if (!fs::exists(rootPath) || !fs::is_directory(rootPath)) { std::cerr << "Error: Root path is invalid or not a directory." << std::endl; return ""; } std::vector validFolderPath; // Step 1: Scan all subdirectories matching projectName + number for (const auto& entry : fs::directory_iterator(rootPath)) { if (entry.is_directory()) { //check if the folder has weights/best.pt // convert entry.path() to string std::string modelPath = entry.path().string() + "\\weights\\best.pt"; // check if this model path is exists if (FileExist(modelPath)) { validFolderPath.emplace_back(entry.path().string()); } else { //delete the folder std::error_code ec; fs::remove_all(entry.path(), ec); } } } // Step 2: the latest folder fs::path selectedFolder; if (!validFolderPath.empty()) { selectedFolder = validFolderPath.back(); } else { return ""; } // Step 3: Delete all other folders except for the selected one if (validFolderPath.size() > 1) { for (const auto& folder : validFolderPath) { if (folder != selectedFolder && fs::exists(folder)) { std::error_code ec; fs::remove_all(folder, ec); } } } // Step 5: Rename the selected folder to the project name std::string newFolderName = rootPath + "\\" + projectName; //if selectedFolder is already the same as newFolderName, return if (selectedFolder == newFolderName) { return selectedFolder.string(); } else {// rename the selected folder to the project name std::error_code ec; fs::rename(selectedFolder, newFolderName, ec); // return new folder name return newFolderName; } } std::string ANSTRE::ExecuteCommand(const char* cmd) { std::string result; // Check if the command string is empty if (cmd == nullptr || std::string(cmd).empty()) { return ""; // Or simply return an empty string if no message is needed } STARTUPINFOA si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES sa; HANDLE hStdOutRead, hStdOutWrite; // Set up the security attributes struct sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = nullptr; // Create a pipe for the child process's STDOUT if (!CreatePipe(&hStdOutRead, &hStdOutWrite, &sa, 0)) { this->_logger.LogFatal("ANSTRE::ExecuteCommand()", "Failed to create pipe", __FILE__, __LINE__); return ""; } // Ensure the read handle to the pipe for STDOUT is not inherited SetHandleInformation(hStdOutRead, HANDLE_FLAG_INHERIT, 0); // Set up STARTUPINFO structure ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si.wShowWindow = SW_HIDE; si.hStdOutput = hStdOutWrite; si.hStdError = hStdOutWrite; // Create the child process std::string command = "cmd.exe /C " + std::string(cmd); ZeroMemory(&pi, sizeof(pi)); if (!CreateProcessA(nullptr, const_cast(command.c_str()), nullptr, nullptr, TRUE, 0, nullptr, nullptr, &si, &pi)) { this->_logger.LogFatal("ANSTRE::ExecuteCommand()", "Failed to start process", __FILE__, __LINE__); CloseHandle(hStdOutWrite); CloseHandle(hStdOutRead); return ""; } // Close the write end of the pipe before reading from the read end CloseHandle(hStdOutWrite); // Read output from the child process DWORD dwRead; CHAR chBuf[4096]; ULONGLONG startTime = GetTickCount64(); ULONGLONG timeoutDuration = 180000; // 3 minutes while (ReadFile(hStdOutRead, chBuf, 4096, &dwRead, nullptr) && dwRead != 0) { result.append(chBuf, dwRead); if ((GetTickCount64() - startTime) > timeoutDuration) break; } // Close the read handle of the pipe CloseHandle(hStdOutRead); // Close process and thread handles CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return result; } std::vector ANSTRE::ParseANSClass(const std::string& ansClassFileName) { std::vector classNames; // Create a property tree and parse the JSON file boost::property_tree::ptree pt; try { boost::property_tree::read_json(ansClassFileName, pt); // Iterate directly through the array for (const auto& arrayElement : pt) { classNames.push_back(arrayElement.second.get("ClassName")); } } catch (const boost::property_tree::ptree_bad_path& e) { std::cerr << "Error: " << e.what() << std::endl; } catch (const boost::property_tree::json_parser_error& e) { std::cerr << "JSON Parsing Error: " << e.what() << std::endl; } return classNames; } std::string ANSTRE::ConvertVectorToClass(const std::vector& vec) { std::ostringstream oss; oss << "["; for (size_t i = 0; i < vec.size(); ++i) { oss << vec[i]; if (i < vec.size() - 1) { oss << ","; } } oss << "]"; return oss.str(); } } extern "C" ANSTRE_API int CreateANSTREHandle(ANSCENTER::ANSTRE** Handle, const char* licenseKey, const char* projectDirectory, const char* engineDirectory, const char* modelTemplateDirectory, const char* modelZipPassword, int trainingEngineType, int latestEngine) { ANS_DBG("ANSTRE","Create called: HandlePtr=%p, *Handle(in)=%p, engineType=%d, latestEngine=%d, projectDir=%s, engineDir=%s", (void*)Handle, (void*)(Handle ? *Handle : nullptr), trainingEngineType, latestEngine, projectDirectory ? projectDirectory : "(null)", engineDirectory ? engineDirectory : "(null)"); if (Handle == nullptr) { ANS_DBG("ANSTRE","Create FAIL: Handle is null"); return 0; } if (licenseKey == nullptr || projectDirectory == nullptr || engineDirectory == nullptr || modelTemplateDirectory == nullptr || modelZipPassword == nullptr) { ANS_DBG("ANSTRE","Create FAIL: one of the string params is null"); return 0; } // Pure constructor: ignore *Handle(in). LabVIEW's CLF Node marshalling // reuses the same temp buffer per call site, so *Handle(in) often holds // leftover bytes from the previous Create's output even when the actual // LabVIEW wire is a different, freshly-allocated instance. Inspecting // *Handle(in) and destroying what we "see" tears down legitimate // parallel instances. (Same reasoning as CreateANSAWSHandle.) // Trade-off: a true double-Create on the same wire leaks the prior // handle -- caller's bug; the alternative is far worse. *Handle = nullptr; try { switch (trainingEngineType) { case 0: (*Handle) = new ANSCENTER::ANSODTRE(); break; case 1: (*Handle) = new ANSCENTER::ANYLTRE(); break; case 2: (*Handle) = new ANSCENTER::ANYLCLTRE(); break; case 3: (*Handle) = new ANSCENTER::ANYLSEGTRE(); break; case 4: (*Handle) = new ANSCENTER::ANYLOBBTRE(); break; default: (*Handle) = new ANSCENTER::ANSODTRE(); break; } if (*Handle == nullptr) { ANS_DBG("ANSTRE","Create FAIL: new returned null"); return 0; } ANS_DBG("ANSTRE","Create: allocated handle=%p (uint=%llu), calling Init...", (void*)*Handle, (unsigned long long)(uintptr_t)*Handle); bool isLatestEngine = (latestEngine == 1) ? true : false; if ((*Handle)->Init(licenseKey, projectDirectory, engineDirectory, modelTemplateDirectory, modelZipPassword, isLatestEngine)) { RegisterTREHandle(*Handle); ANS_DBG("ANSTRE","Create OK: handle=%p (uint=%llu)", (void*)*Handle, (unsigned long long)(uintptr_t)*Handle); return 1; } ANS_DBG("ANSTRE","Create FAIL: Init returned false, deleting handle=%p", (void*)*Handle); delete *Handle; *Handle = nullptr; return 0; } catch (std::exception& e) { ANS_DBG("ANSTRE","Create EXCEPTION (std::exception): %s", e.what()); if (*Handle != nullptr) { delete *Handle; *Handle = nullptr; } return 0; } catch (...) { ANS_DBG("ANSTRE","Create EXCEPTION (unknown)"); if (*Handle != nullptr) { delete *Handle; *Handle = nullptr; } return 0; } } static int ReleaseANSTREHandle_Impl(ANSCENTER::ANSTRE** Handle) { try { if (!Handle || !*Handle) { ANS_DBG("ANSTRE","Release: HandlePtr or *Handle is null, no-op"); return 1; } ANSCENTER::ANSTRE* h = *Handle; ANS_DBG("ANSTRE","Release called: handle=%p (uint=%llu)", (void*)h, (unsigned long long)(uintptr_t)h); if (!UnregisterTREHandle(h)) { ANS_DBG("ANSTRE","Release: Unregister returned false (already gone or being destroyed by another thread), handle=%p", (void*)h); *Handle = nullptr; return 1; } delete h; *Handle = nullptr; ANS_DBG("ANSTRE","Release OK: handle=%p deleted, registry now has %zu entries", (void*)h, TREHandleRegistry().size()); return 1; } catch (...) { ANS_DBG("ANSTRE","Release EXCEPTION (unknown)"); if (Handle) *Handle = nullptr; return 0; } } extern "C" ANSTRE_API int ReleaseANSTREHandle(ANSCENTER::ANSTRE** Handle) { __try { return ReleaseANSTREHandle_Impl(Handle); } __except (EXCEPTION_EXECUTE_HANDLER) { ANS_DBG("ANSTRE","ReleaseANSTREHandle: SEH exception caught"); if (Handle) *Handle = nullptr; return 0; } } extern "C" ANSTRE_API int ANSTRE_GetProjects(ANSCENTER::ANSTRE** Handle, LStrHandle strProjects) { ANS_DBG("ANSTRE","ANSTRE_GetProjects: HandlePtr=%p, *Handle=%p", (void*)Handle, (void*)(Handle ? *Handle : nullptr)); if (Handle == nullptr || strProjects == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::vector projects = guard.get()->GetProjects(); std::string st = VectorToSeparatedString(projects); int size = (int)st.length(); MgErr error; error = DSSetHandleSize(strProjects, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*strProjects)->cnt = size; memcpy((*strProjects)->str, st.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GetProjectExperiments(ANSCENTER::ANSTRE** Handle, const char* projectName, LStrHandle strProjectExperiments) { ANS_DBG("ANSTRE","ANSTRE_GetProjectExperiments: HandlePtr=%p, *Handle=%p, project=%s", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)"); if (Handle == nullptr || projectName == nullptr || strProjectExperiments == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::vector experiments = guard.get()->GetProjectExperiments(projectName); std::string st = VectorToSeparatedString(experiments); int size = (int)st.length(); MgErr error; error = DSSetHandleSize(strProjectExperiments, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*strProjectExperiments)->cnt = size; memcpy((*strProjectExperiments)->str, st.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_CreateProject(ANSCENTER::ANSTRE** Handle, const char* projectName) { ANS_DBG("ANSTRE","ANSTRE_CreateProject: HandlePtr=%p, *Handle=%p, project=%s", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)"); if (Handle == nullptr || projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; if (guard.get()->CreateProject(stProjectName))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_DeleteProject(ANSCENTER::ANSTRE** Handle, const char* projectName) { ANS_DBG("ANSTRE","ANSTRE_DeleteProject: HandlePtr=%p, *Handle=%p, project=%s", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)"); if (Handle == nullptr || projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; if (guard.get()->DeleteProject(stProjectName))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_SetWorkingDirectory(ANSCENTER::ANSTRE** Handle, const char* workingDirectory) { ANS_DBG("ANSTRE","ANSTRE_SetWorkingDirectory: HandlePtr=%p, *Handle=%p, dir=%s", (void*)Handle, (void*)(Handle ? *Handle : nullptr), workingDirectory ? workingDirectory : "(null)"); if (Handle == nullptr || workingDirectory == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stWorkingDirectory = workingDirectory; if (guard.get()->SetWorkingDirectory(stWorkingDirectory))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_UploadTrainingData(ANSCENTER::ANSTRE** Handle, const char* projectName) { ANS_DBG("ANSTRE","ANSTRE_UploadTrainingData: HandlePtr=%p, *Handle=%p, project=%s", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)"); if (Handle == nullptr || projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; if (guard.get()->UploadTrainingData(stProjectName))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_CreateTrainingEngine(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, int extractorType, long numberStep, int batchSize, double learningRate) { ANS_DBG("ANSTRE","ANSTRE_CreateTrainingEngine: HandlePtr=%p, *Handle=%p, project=%s, exp=%d, extractor=%d, steps=%ld, batch=%d, lr=%f", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber, extractorType, numberStep, batchSize, learningRate); if (Handle == nullptr || projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; if (guard.get()->CreateTrainingEngine(stProjectName, experimentNumber, extractorType, numberStep, batchSize, learningRate))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GetProjectExperimentStatus(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, LStrHandle projectStatus) { ANS_DBG("ANSTRE","ANSTRE_GetProjectExperimentStatus: HandlePtr=%p, *Handle=%p, project=%s, exp=%d", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber); if (Handle == nullptr || projectName == nullptr || projectStatus == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; std::string stProjectStatus = guard.get()->GetProjectExperimentStatus(stProjectName, experimentNumber); int size = (int)stProjectStatus.length(); MgErr error; error = DSSetHandleSize(projectStatus, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*projectStatus)->cnt = size; memcpy((*projectStatus)->str, stProjectStatus.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GenerateTrainingCommand(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, int extractorType, LStrHandle trainingCommand) { ANS_DBG("ANSTRE","ANSTRE_GenerateTrainingCommand: HandlePtr=%p, *Handle=%p, project=%s, exp=%d, extractor=%d", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber, extractorType); if (Handle == nullptr || projectName == nullptr || trainingCommand == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; std::string stTrainingCommand = guard.get()->GenerateTrainingCommand(stProjectName, experimentNumber, extractorType); int size = (int)stTrainingCommand.length(); MgErr error; error = DSSetHandleSize(trainingCommand, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*trainingCommand)->cnt = size; memcpy((*trainingCommand)->str, stTrainingCommand.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GenerateCustomTrainingCommand(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, int extractorType, const char* pretrainedModel, LStrHandle trainingCommand) { ANS_DBG("ANSTRE","ANSTRE_GenerateCustomTrainingCommand: HandlePtr=%p, *Handle=%p, project=%s, exp=%d, extractor=%d, pretrained=%s", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber, extractorType, pretrainedModel ? pretrainedModel : "(null)"); if (Handle == nullptr || projectName == nullptr || pretrainedModel == nullptr || trainingCommand == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; std::string stTrainingCommand = guard.get()->GenerateCustomTrainingCommand(stProjectName, experimentNumber, extractorType, pretrainedModel); int size = (int)stTrainingCommand.length(); MgErr error; error = DSSetHandleSize(trainingCommand, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*trainingCommand)->cnt = size; memcpy((*trainingCommand)->str, stTrainingCommand.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_EvaluateModel(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, LStrHandle mAPResult) { ANS_DBG("ANSTRE","ANSTRE_EvaluateModel: HandlePtr=%p, *Handle=%p, project=%s, exp=%d", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber); if (Handle == nullptr || projectName == nullptr || mAPResult == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; std::string stmAPResult = guard.get()->EvaluateModel(stProjectName, experimentNumber); int size = (int)stmAPResult.length(); MgErr error; error = DSSetHandleSize(mAPResult, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*mAPResult)->cnt = size; memcpy((*mAPResult)->str, stmAPResult.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_DownloadModel(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, const char* downloadDirDestination, int modelMode) { ANS_DBG("ANSTRE","ANSTRE_DownloadModel: HandlePtr=%p, *Handle=%p, project=%s, exp=%d, dest=%s, mode=%d", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber, downloadDirDestination ? downloadDirDestination : "(null)", modelMode); if (Handle == nullptr || projectName == nullptr || downloadDirDestination == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; bool downloadResult = guard.get()->DownloadModel(stProjectName, experimentNumber, downloadDirDestination, modelMode); if (downloadResult)return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GetProjectDirectory(ANSCENTER::ANSTRE** Handle, LStrHandle strProjectDir) { ANS_DBG("ANSTRE","ANSTRE_GetProjectDirectory: HandlePtr=%p, *Handle=%p", (void*)Handle, (void*)(Handle ? *Handle : nullptr)); if (Handle == nullptr || strProjectDir == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectDir = guard.get()->GetProjectDirectory(); int size = (int)stProjectDir.length(); MgErr error; error = DSSetHandleSize(strProjectDir, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*strProjectDir)->cnt = size; memcpy((*strProjectDir)->str, stProjectDir.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_ZipExperiment(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber) { ANS_DBG("ANSTRE","ANSTRE_ZipExperiment: HandlePtr=%p, *Handle=%p, project=%s, exp=%d", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber); if (Handle == nullptr || projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; if (guard.get()->ZipExperiment(stProjectName, experimentNumber))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API double ANSTRE_ParseMAP(ANSCENTER::ANSTRE** Handle, const char* evaluationResult) { ANS_DBG("ANSTRE","ANSTRE_ParseMAP: HandlePtr=%p, *Handle=%p", (void*)Handle, (void*)(Handle ? *Handle : nullptr)); if (Handle == nullptr || evaluationResult == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stEvaluationResult = evaluationResult; return guard.get()->ParseObjectDetectionMAP(stEvaluationResult); } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_ParseTrainingResults(ANSCENTER::ANSTRE** Handle, const char* trainingResult, LStrHandle strResult) { ANS_DBG("ANSTRE","ANSTRE_ParseTrainingResults: HandlePtr=%p, *Handle=%p", (void*)Handle, (void*)(Handle ? *Handle : nullptr)); if (Handle == nullptr || trainingResult == nullptr || strResult == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stTrainingResult = trainingResult; std::string stResult = guard.get()->ParseTrainingResults(stTrainingResult); int size = (int)stResult.length(); MgErr error; error = DSSetHandleSize(strResult, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*strResult)->cnt = size; memcpy((*strResult)->str, stResult.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } //CPP interface extern "C" ANSTRE_API int ANSTRE_GetProjects_CPP(ANSCENTER::ANSTRE** Handle, std::string& strProjects) { ANS_DBG("ANSTRE","ANSTRE_GetProjects_CPP: HandlePtr=%p, *Handle=%p", (void*)Handle, (void*)(Handle ? *Handle : nullptr)); if (Handle == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::vector projects = guard.get()->GetProjects(); strProjects = VectorToSeparatedString(projects); return 1; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GetProjectExperiments_CPP(ANSCENTER::ANSTRE** Handle, const char* projectName, std::string& strProjectExperiments) { ANS_DBG("ANSTRE","ANSTRE_GetProjectExperiments_CPP: HandlePtr=%p, *Handle=%p, project=%s", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)"); if (Handle == nullptr || projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::vector experiments = guard.get()->GetProjectExperiments(projectName); strProjectExperiments = VectorToSeparatedString(experiments); return 1; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GetProjectExperimentStatus_CPP(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, std::string& projectStatus) { ANS_DBG("ANSTRE","ANSTRE_GetProjectExperimentStatus_CPP: HandlePtr=%p, *Handle=%p, project=%s, exp=%d", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber); if (Handle == nullptr || projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; projectStatus = guard.get()->GetProjectExperimentStatus(stProjectName, experimentNumber); return 1; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GenerateTrainingCommand_CPP(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, int extractorType, std::string& trainingCommand) { ANS_DBG("ANSTRE","ANSTRE_GenerateTrainingCommand_CPP: HandlePtr=%p, *Handle=%p, project=%s, exp=%d, extractor=%d", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber, extractorType); if (Handle == nullptr || projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; trainingCommand = guard.get()->GenerateTrainingCommand(stProjectName, experimentNumber, extractorType); return 1; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GenerateCustomTrainingCommand_CPP(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, int extractorType, const char* pretrainedModel, std::string& trainingCommand) { ANS_DBG("ANSTRE","ANSTRE_GenerateCustomTrainingCommand_CPP: HandlePtr=%p, *Handle=%p, project=%s, exp=%d, extractor=%d, pretrained=%s", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber, extractorType, pretrainedModel ? pretrainedModel : "(null)"); if (Handle == nullptr || projectName == nullptr || pretrainedModel == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; trainingCommand = guard.get()->GenerateCustomTrainingCommand(stProjectName, experimentNumber, extractorType, pretrainedModel); return 1; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_EvaluateModel_CPP(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, std::string& mAPResult) { ANS_DBG("ANSTRE","ANSTRE_EvaluateModel_CPP: HandlePtr=%p, *Handle=%p, project=%s, exp=%d", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber); if (Handle == nullptr || projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; mAPResult = guard.get()->EvaluateModel(stProjectName, experimentNumber); return 1; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_EvaluateModelOnTestData_CPP(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, const char* dataFolder,std::string& evaluationCommand) { ANS_DBG("ANSTRE","ANSTRE_EvaluateModelOnTestData_CPP: HandlePtr=%p, *Handle=%p, project=%s, exp=%d, dataFolder=%s", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber, dataFolder ? dataFolder : "(null)"); if (Handle == nullptr || projectName == nullptr || dataFolder == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; bool zipModelExist = false; evaluationCommand = guard.get()->GenerateTestCommand(stProjectName, experimentNumber, zipModelExist, dataFolder); if (evaluationCommand.empty()) { return 0; } else { return 1; } } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_EvaluateModelOnTestData(ANSCENTER::ANSTRE** Handle, const char* projectName, int experimentNumber, const char* dataFolder, LStrHandle evaluationCommand) { ANS_DBG("ANSTRE","ANSTRE_EvaluateModelOnTestData: HandlePtr=%p, *Handle=%p, project=%s, exp=%d, dataFolder=%s", (void*)Handle, (void*)(Handle ? *Handle : nullptr), projectName ? projectName : "(null)", experimentNumber, dataFolder ? dataFolder : "(null)"); if (Handle == nullptr || projectName == nullptr || dataFolder == nullptr || evaluationCommand == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stProjectName = projectName; bool zipModelExist = false; std::string evaluationCommandStr = guard.get()->GenerateTestCommand(stProjectName, experimentNumber, zipModelExist, dataFolder); int size = (int)evaluationCommandStr.length(); MgErr error; error = DSSetHandleSize(evaluationCommand, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*evaluationCommand)->cnt = size; memcpy((*evaluationCommand)->str, evaluationCommandStr.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GetProjectDirectory_CPP(ANSCENTER::ANSTRE** Handle, std::string& strProjectDir) { ANS_DBG("ANSTRE","ANSTRE_GetProjectDirectory_CPP: HandlePtr=%p, *Handle=%p", (void*)Handle, (void*)(Handle ? *Handle : nullptr)); if (Handle == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { strProjectDir = guard.get()->GetProjectDirectory(); return 1; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_ParseTrainingResults_CPP(ANSCENTER::ANSTRE** Handle, const char* trainingResult, std::string& strResult) { ANS_DBG("ANSTRE","ANSTRE_ParseTrainingResults_CPP: HandlePtr=%p, *Handle=%p", (void*)Handle, (void*)(Handle ? *Handle : nullptr)); if (Handle == nullptr || trainingResult == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { std::string stTrainingResult = trainingResult; strResult = guard.get()->ParseTrainingResults(stTrainingResult); return 1; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_CheckEngineStatus(ANSCENTER::ANSTRE** Handle) { ANS_DBG("ANSTRE","ANSTRE_CheckEngineStatus: HandlePtr=%p, *Handle=%p", (void*)Handle, (void*)(Handle ? *Handle : nullptr)); if (Handle == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { bool bResult = guard.get()->CheckEngineStatus(); if (bResult) return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_CheckEngine(ANSCENTER::ANSTRE** Handle) { ANS_DBG("ANSTRE","ANSTRE_CheckEngine: HandlePtr=%p, *Handle=%p", (void*)Handle, (void*)(Handle ? *Handle : nullptr)); if (Handle == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(*Handle)); if (!guard) return 0; try { bool bResult = guard.get()->CheckEngine(); if (bResult) return 1; else return 0; } catch (...) { return 0; } } // ============================================================================ // V2 API — accepts uint64_t handleVal by value instead of ANSTRE** Handle. // Eliminates LabVIEW buffer-reuse bug when concurrent calls share the same // Handle** buffer address. // ============================================================================ extern "C" ANSTRE_API int ANSTRE_GetProjects_V2(uint64_t handleVal, LStrHandle strProjects) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_GetProjects_V2: handleVal=%llu handle=%p", (unsigned long long)handleVal, (void*)_v2h); if (!_v2h) return 0; if (strProjects == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::vector projects = guard.get()->GetProjects(); std::string st = VectorToSeparatedString(projects); int size = (int)st.length(); MgErr error; error = DSSetHandleSize(strProjects, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*strProjects)->cnt = size; memcpy((*strProjects)->str, st.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GetProjectExperiments_V2(uint64_t handleVal, const char* projectName, LStrHandle strProjectExperiments) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_GetProjectExperiments_V2: handleVal=%llu handle=%p, project=%s", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)"); if (!_v2h) return 0; if (projectName == nullptr || strProjectExperiments == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::vector experiments = guard.get()->GetProjectExperiments(projectName); std::string st = VectorToSeparatedString(experiments); int size = (int)st.length(); MgErr error; error = DSSetHandleSize(strProjectExperiments, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*strProjectExperiments)->cnt = size; memcpy((*strProjectExperiments)->str, st.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_CreateProject_V2(uint64_t handleVal, const char* projectName) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_CreateProject_V2: handleVal=%llu handle=%p, project=%s", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)"); if (!_v2h) return 0; if (projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectName = projectName; if (guard.get()->CreateProject(stProjectName))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_DeleteProject_V2(uint64_t handleVal, const char* projectName) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_DeleteProject_V2: handleVal=%llu handle=%p, project=%s", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)"); if (!_v2h) return 0; if (projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectName = projectName; if (guard.get()->DeleteProject(stProjectName))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_SetWorkingDirectory_V2(uint64_t handleVal, const char* workingDirectory) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_SetWorkingDirectory_V2: handleVal=%llu handle=%p, dir=%s", (unsigned long long)handleVal, (void*)_v2h, workingDirectory ? workingDirectory : "(null)"); if (!_v2h) return 0; if (workingDirectory == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stWorkingDirectory = workingDirectory; if (guard.get()->SetWorkingDirectory(stWorkingDirectory))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_UploadTrainingData_V2(uint64_t handleVal, const char* projectName) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_UploadTrainingData_V2: handleVal=%llu handle=%p, project=%s", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)"); if (!_v2h) return 0; if (projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectName = projectName; if (guard.get()->UploadTrainingData(stProjectName))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_CreateTrainingEngine_V2(uint64_t handleVal, const char* projectName, int experimentNumber, int extractorType, long numberStep, int batchSize, double learningRate) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_CreateTrainingEngine_V2: handleVal=%llu handle=%p, project=%s, exp=%d, extractor=%d, steps=%ld, batch=%d, lr=%f", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)", experimentNumber, extractorType, numberStep, batchSize, learningRate); if (!_v2h) return 0; if (projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectName = projectName; if (guard.get()->CreateTrainingEngine(stProjectName, experimentNumber, extractorType, numberStep, batchSize, learningRate))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GetProjectExperimentStatus_V2(uint64_t handleVal, const char* projectName, int experimentNumber, LStrHandle projectStatus) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_GetProjectExperimentStatus_V2: handleVal=%llu handle=%p, project=%s, exp=%d", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)", experimentNumber); if (!_v2h) return 0; if (projectName == nullptr || projectStatus == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectName = projectName; std::string stProjectStatus = guard.get()->GetProjectExperimentStatus(stProjectName, experimentNumber); int size = (int)stProjectStatus.length(); MgErr error; error = DSSetHandleSize(projectStatus, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*projectStatus)->cnt = size; memcpy((*projectStatus)->str, stProjectStatus.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GenerateTrainingCommand_V2(uint64_t handleVal, const char* projectName, int experimentNumber, int extractorType, LStrHandle trainingCommand) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_GenerateTrainingCommand_V2: handleVal=%llu handle=%p, project=%s, exp=%d, extractor=%d", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)", experimentNumber, extractorType); if (!_v2h) return 0; if (projectName == nullptr || trainingCommand == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectName = projectName; std::string stTrainingCommand = guard.get()->GenerateTrainingCommand(stProjectName, experimentNumber, extractorType); int size = (int)stTrainingCommand.length(); MgErr error; error = DSSetHandleSize(trainingCommand, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*trainingCommand)->cnt = size; memcpy((*trainingCommand)->str, stTrainingCommand.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GenerateCustomTrainingCommand_V2(uint64_t handleVal, const char* projectName, int experimentNumber, int extractorType, const char* pretrainedModel, LStrHandle trainingCommand) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_GenerateCustomTrainingCommand_V2: handleVal=%llu handle=%p, project=%s, exp=%d, extractor=%d, pretrained=%s", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)", experimentNumber, extractorType, pretrainedModel ? pretrainedModel : "(null)"); if (!_v2h) return 0; if (projectName == nullptr || pretrainedModel == nullptr || trainingCommand == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectName = projectName; std::string stTrainingCommand = guard.get()->GenerateCustomTrainingCommand(stProjectName, experimentNumber, extractorType, pretrainedModel); int size = (int)stTrainingCommand.length(); MgErr error; error = DSSetHandleSize(trainingCommand, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*trainingCommand)->cnt = size; memcpy((*trainingCommand)->str, stTrainingCommand.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_EvaluateModel_V2(uint64_t handleVal, const char* projectName, int experimentNumber, LStrHandle mAPResult) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_EvaluateModel_V2: handleVal=%llu handle=%p, project=%s, exp=%d", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)", experimentNumber); if (!_v2h) return 0; if (projectName == nullptr || mAPResult == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectName = projectName; std::string stmAPResult = guard.get()->EvaluateModel(stProjectName, experimentNumber); int size = (int)stmAPResult.length(); MgErr error; error = DSSetHandleSize(mAPResult, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*mAPResult)->cnt = size; memcpy((*mAPResult)->str, stmAPResult.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_EvaluateModelOnTestData_V2(uint64_t handleVal, const char* projectName, int experimentNumber, const char* dataFolder, LStrHandle evaluationCommand) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_EvaluateModelOnTestData_V2: handleVal=%llu handle=%p, project=%s, exp=%d, dataFolder=%s", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)", experimentNumber, dataFolder ? dataFolder : "(null)"); if (!_v2h) return 0; if (projectName == nullptr || dataFolder == nullptr || evaluationCommand == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectName = projectName; bool zipModelExist = false; std::string evaluationCommandStr = guard.get()->GenerateTestCommand(stProjectName, experimentNumber, zipModelExist, dataFolder); int size = (int)evaluationCommandStr.length(); MgErr error; error = DSSetHandleSize(evaluationCommand, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*evaluationCommand)->cnt = size; memcpy((*evaluationCommand)->str, evaluationCommandStr.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_DownloadModel_V2(uint64_t handleVal, const char* projectName, int experimentNumber, const char* downloadDirDestination, int modelMode) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_DownloadModel_V2: handleVal=%llu handle=%p, project=%s, exp=%d, dest=%s, mode=%d", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)", experimentNumber, downloadDirDestination ? downloadDirDestination : "(null)", modelMode); if (!_v2h) return 0; if (projectName == nullptr || downloadDirDestination == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectName = projectName; bool downloadResult = guard.get()->DownloadModel(stProjectName, experimentNumber, downloadDirDestination, modelMode); if (downloadResult)return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_GetProjectDirectory_V2(uint64_t handleVal, LStrHandle strProjectDir) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_GetProjectDirectory_V2: handleVal=%llu handle=%p", (unsigned long long)handleVal, (void*)_v2h); if (!_v2h) return 0; if (strProjectDir == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectDir = guard.get()->GetProjectDirectory(); int size = (int)stProjectDir.length(); MgErr error; error = DSSetHandleSize(strProjectDir, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*strProjectDir)->cnt = size; memcpy((*strProjectDir)->str, stProjectDir.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_ZipExperiment_V2(uint64_t handleVal, const char* projectName, int experimentNumber) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_ZipExperiment_V2: handleVal=%llu handle=%p, project=%s, exp=%d", (unsigned long long)handleVal, (void*)_v2h, projectName ? projectName : "(null)", experimentNumber); if (!_v2h) return 0; if (projectName == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stProjectName = projectName; if (guard.get()->ZipExperiment(stProjectName, experimentNumber))return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API double ANSTRE_ParseMAP_V2(uint64_t handleVal, const char* evaluationResult) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_ParseMAP_V2: handleVal=%llu handle=%p", (unsigned long long)handleVal, (void*)_v2h); if (!_v2h) return 0.0; if (evaluationResult == nullptr) return 0.0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0.0; try { std::string stEvaluationResult = evaluationResult; return guard.get()->ParseObjectDetectionMAP(stEvaluationResult); } catch (...) { return 0.0; } } extern "C" ANSTRE_API int ANSTRE_ParseTrainingResults_V2(uint64_t handleVal, const char* trainingResult, LStrHandle strResult) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_ParseTrainingResults_V2: handleVal=%llu handle=%p", (unsigned long long)handleVal, (void*)_v2h); if (!_v2h) return 0; if (trainingResult == nullptr || strResult == nullptr) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { std::string stTrainingResult = trainingResult; std::string stResult = guard.get()->ParseTrainingResults(stTrainingResult); int size = (int)stResult.length(); MgErr error; error = DSSetHandleSize(strResult, sizeof(int32) + size * sizeof(uChar)); if (error == noErr) { (*strResult)->cnt = size; memcpy((*strResult)->str, stResult.c_str(), size); return 1; } else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_CheckEngineStatus_V2(uint64_t handleVal) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_CheckEngineStatus_V2: handleVal=%llu handle=%p", (unsigned long long)handleVal, (void*)_v2h); if (!_v2h) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { bool bResult = guard.get()->CheckEngineStatus(); if (bResult) return 1; else return 0; } catch (...) { return 0; } } extern "C" ANSTRE_API int ANSTRE_CheckEngine_V2(uint64_t handleVal) { auto* _v2h = reinterpret_cast(handleVal); ANS_DBG("ANSTRE","ANSTRE_CheckEngine_V2: handleVal=%llu handle=%p", (unsigned long long)handleVal, (void*)_v2h); if (!_v2h) return 0; TREHandleGuard guard(AcquireTREHandle(_v2h)); if (!guard) return 0; try { bool bResult = guard.get()->CheckEngine(); if (bResult) return 1; else return 0; } catch (...) { return 0; } }