You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C++项目中从应用目录加载onnxruntime.dll遇126错误,仍加载系统旧版本的问题求助

C++项目中从应用目录加载onnxruntime.dll遇126错误,仍加载系统旧版本的问题求助

各位大佬好,我现在碰到一个棘手的问题:我在C++项目里想使用应用目录下的ONNX Runtime 1.22.0版本,已经在Visual Studio的项目属性里配置了包含目录、库目录、链接器选项,还加了预构建事件把对应的onnxruntime.dll复制到了应用输出目录里。

但实际运行时,我用LoadLibraryEx加载dll的时候,程序总是自动去C:\Windows\System32里找旧版本(1.17)的onnxruntime.dll。我尝试通过设置LOAD_LIBRARY_SEARCH_USER_DIRS标志,加上调用AddDllDirectory把dll所在目录添加到搜索路径里,写了下面这段加载代码:

// Load ONNX Runtime DLL from this DLL's path
static bool LoadONNXRuntime() {
    // Get the module handle for the current DLL.
    HMODULE hCurrentModule = NULL;
    if (!GetModuleHandleEx(
        GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
        reinterpret_cast<LPCTSTR>(&LoadONNXRuntime),
        &hCurrentModule)) {
        LOG_ERROR("GetModuleHandleEx failed. Error: {}", GetLastError());
        return false;
    }

    // Retrieve the full path of the current DLL.
    TCHAR modulePath[MAX_PATH] = { 0 };
    if (GetModuleFileName(hCurrentModule, modulePath, MAX_PATH) == 0) {
        LOG_ERROR("GetModuleFileName failed. Error: {}", GetLastError());
        return false;
    }

    // Extract the directory from the full path.
    std::basic_string<TCHAR> pathStr(modulePath);
    size_t pos = pathStr.find_last_of(TEXT("\\/"));
    if (pos == std::basic_string<TCHAR>::npos) {
        LOG_ERROR("Failed to parse module path");
        return false;
    }
    std::basic_string<TCHAR> dllDirectory = pathStr.substr(0, pos + 1);

    // Set default DLL directories to avoid system library conflicts
    if (!SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_USER_DIRS | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) {
        LOG_ERROR("SetDefaultDllDirectories failed. Error: {}", GetLastError());
        return false;
    }

    // Add the custom directory to the DLL search path
    DLL_DIRECTORY_COOKIE cookie = AddDllDirectory(dllDirectory.c_str());
    if (cookie == NULL) {
        LOG_ERROR("AddDllDirectory failed. Error: {}", GetLastError());
        return false;
    }

    // Construct the full path to the DLL file.
    std::basic_string<TCHAR> dependentDllPath = dllDirectory + TEXT("onnxruntime.dll");
    LOG_INFO("Loading ONNX Runtime DLL from: {}", std::string(dependentDllPath.begin(), dependentDllPath.end()));

    // Load the dependent DLL using user-specified directories for dependency resolution
    HMODULE hDependent = LoadLibraryEx(dependentDllPath.c_str(), NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
    if (hDependent == NULL) {
        LOG_ERROR("LoadLibraryEx failed. Error: {}", GetLastError());
        return false;
    }

    LOG_INFO("Successfully loaded the ONNX Runtime DLL. ONNX Runtime Version is: {}", Ort::GetVersionString());
    return true;
}

现在的问题是,这段代码执行时LoadLibraryEx返回错误码126,而且最后程序还是加载了系统目录里的1.17版本,导致后续执行Ort::Env env = Ort::Env(ORT_LOGGING_LEVEL_WARNING, "OnnxRTInference");时因为API版本不兼容报错。

我想请教一下:

  • 是不是我设置DLL搜索路径的方式有问题?
  • LoadLibraryEx的参数使用是否正确?有没有其他参数可以强制优先加载本地目录的dll?
  • 有没有什么办法彻底避免程序去系统目录找旧版本的onnxruntime.dll?

感谢各位的帮忙!

内容来源于stack exchange

火山引擎 最新活动