如何让我自己的dll在特定位置使用dll?
我已经构建了一个32位的Excel dll(一个.xll)。我在dll中使用Python C-Api。问题一般只有64位Python安装。 64 python26.dll位于\ System32。 如果我把32位python26.dll放在Excel exe文件夹或\ SysWOW64中一切都很好,但通常我无法访问这些文件夹。将32位python dll放在xll文件夹中没有用,似乎是\ System32首先出现。
我有没有明确使用“LoadLibrary”和多次“GetProcAddress”链接的解决方案。 VS2010中的任何选项?
非常感谢你的帮助。
答案 0 :(得分:1)
你是对的,搜索顺序首先是系统目录(和for a reason)。这是插件的传统情况。应用程序本身可以将它们的依赖库存储在它们自己的程序文件夹中并且没问题,因为它具有最高优先级。插件通常不具备这种奢侈品。
解决方案可能是使用DLL的延迟加载。如果您有这样的程序:
int main()
{
Py_Initialize();
}
...并将其与python26.lib
相关联,它将在导入表中创建一个静态条目,指向python26.dll!Py_Initialize
。由于导入表是在代码运行之前处理的,因此您无法说出要使用哪个python26.dll
,在哪里找到它等。
但是如果你设置链接器标志/DELAYLOAD:python26.dll
并将MSVC delayimp.lib
添加到构建中,它将推迟加载Python DLL,直到调用它的某个函数。所以现在你可以确保你加载正确的:导入表只有依赖的基本名称(python26.dll
),如果已经加载了一些同名的库,它只会重复使用它。所以你可以从你选择的任何位置预加载你想要的那个,然后让延迟的加载器完成它的工作,如下所示:
int main()
{
LoadLibrary(TEXT("C:\\Program Files (x86)\\...\\...\\python26.dll"));
Py_Initialize();
}
但即使如此,你可能还会面临另一个问题。默认情况下使用具有正确基本名称的第一个加载模块这一事实意味着即使您设法正确执行其他所有操作,仍可能存在其他一些Excel插件或加载了一些愚蠢的Shell扩展(例如,当用户转到"打开文件"对话框),这将加载他们自己的python26.dll
,其中包含可能不兼容的API,使用其他编译器或其他任何东西构建,这可能会毁了你的一天。
因此,我还建议您将自己的自定义版本重命名为productname-python26.dll
,并链接到该版本。肯定永远不会有任何其他产品的类似命名DLL,所以你会安全。要从重命名的DLL创建.lib文件,请尝试例如this guide