在给Adobe Premiere/After Effects等后期制作软件开发第三方插件的时候,我们总希望插件依赖的动态库能够脱离插件的位置,单独存储到另外一个地方。这样一方面可以与其他程序共享这些动态库,还能保证插件安装时非常的清爽。就Adobe Premiere Pro/After Effects来说,插件文件是放到C:\Program Files\Adobe\Common\Plug-ins\7.0\MediaCore(Windows平台)的。这个是PremierePro和AfterEffects的公共插件目录,二者在启动的时候都会尝试去这个位置加载插件。与此同时,我们希望自己开发的插件所依赖的动态库放到另外的位置,另外也希望插件显示链接的动态库能够尽量少。因为如果是显式链接的话,这些插件依赖的动态库必须和插件保存在同一个位置。不然插件找不到这些依赖文件就会加载失败的。当然,我们也可以在环境变量里面增加一条路径,但是这容易污染环境变量,或者与其他的程序库产生冲突。LoadLibrary在这个时候就产生作用了。LoadLibrary通过将指定路径的动态库加载到当前的调用进程,然后获取其导出的函数就可以正常使用了。对于像第三方插件这样的应用场景,LoadLibrary可以说是个不错的实现方式。但是正因此也有个弊端,我们无法使用工具得知其的依赖库。
二、使用实例我们在给Adobe Premiere Pro开发的一款插件中,正是使用了这种方法:
(1)首先从注册表中获取到我们插件依赖的动态库文件所在的位置:
1 bool GetInstallationPath(std::string& result) { 2 DWORD data_type; 3 CHAR value[1024]; 4 PVOID pv_data = value; 5 DWORD size = sizeof(value); 6 auto err = RegGetValue(HKEY_CLASSES_ROOT, "test_app\\plugin", "install_location", RRF_RT_ANY, &data_type, pv_data, &size); 7 if (err == ERROR_SUCCESS) { 8 std::string filepath(value); 9 std::regex_replace(std::back_inserter(result), filepath.begin(), filepath.end(), std::regex("[\\\\/]+[^\\\\/]+$"), ""); 10 return true; 11 } 12 return false; 13 }