之前项目中发现的问题,记录下解决方案
1. 问题背景
OVVRNTool项目中,底层图像基本操作功能由DLL库函数提供,上层基于DLL封装了两个应用CMD和GUI,然后通过Qt打包分发;
发布是直接采用绿色免安装的方式打包,具体使用release中的exe进行windeployqt的方式将依赖库等打包进一个文件夹;
由于CMD的特殊性,命令行工具用户只希望出现一个单独的exe,而不想要一个文件夹,包含一大堆库和文件,所以采用enigma virtual box工具将文件夹打包成单个exe;
这时发现一个奇怪的问题,当运行系统CMD时,直接调用exe(不管是enigma打包的还是文件夹中的)会报错,找不到DLL库函数配置文件(同事开发的底层库);但是运行CMD,cd到exe当前目录,就没有问题;
2. 问题定位
通过打印库运行时配置文件路径,定位出现该问题是因为DLL找不到它同路径下的配置文件;
底层库默认配置文件和它在一个路径下,在读取配置文件使用了相对路径;系统CMD启动是在C盘,这时候调用exe,导致库认为运行目录在C盘,导致相对路径出错,找不到配置文件。
3. 解决方案
在DLL库调用配置文件时,先获取自身所在的路径,然后拼接配置文件路径(Windows下获取dll完整路径的方法)
#include <windows.h> #include <string>
//windows下获取当前dll的句柄 HMODULE GetSelfModuleHandle() { MEMORY_BASIC_INFORMATION mbi; return ((::VirtualQuery(GetSelfModuleHandle, &mbi, sizeof(mbi)) != 0) ? (HMODULE)mbi.AllocationBase : NULL); } //在程序中通过调用该函数即可获取到dll的完整路径至strDllFullPath中 void GetFullPathOfDll(std::string& strDllFullPath) { char szPath[MAX_PATH]; GetModuleFileNameA(GetSelfModuleHandle(),szPath,MAX_PATH); strDllFullPath = std::string(szPath); } |