【问题标题】:Link to a dll in specific location in VS2010 c++链接到 VS2010 c++ 中特定位置的 dll
【发布时间】:2014-07-14 14:47:51
【问题描述】:

如何获取自己的 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有什么选项吗?

非常感谢您的帮助。

【问题讨论】:

  • 将 DLL 的路径添加到您的搜索目录或执行 #pragma comment(lib, "path to dll") 我不确定编译指示是否有效,但希望可以。硬编码路径通常不是一个好主意。相对路径更好。
  • 感谢您的建议,但是编译指示不起作用,\System32\之前搜索过。

标签: python c++ visual-studio-2010 dll


【解决方案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.

【讨论】:

  • 谢谢Yirkha。然后我还必须删除链接器选项中对python26.lib的附加依赖项,因为在.lib文件中声明了python27.dll。如果我这样做,我有未解决的导入,我必须为每个使用的函数执行 GetProcAddress 并相应地修改 python.h。我做对了吗?但是DELAYLOAD 那么有什么优势呢?
  • 不,您仍将.lib 保留在那里(但标记为延迟加载),然后在从其他地方调用第一个 Python 函数之前显式加载 DLL。我已经重写了答案以更详细地描述这一点。
  • 现在我明白了。关键是自定义库。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2016-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-23
  • 2012-05-17
  • 1970-01-01
  • 2012-02-29
相关资源
最近更新 更多