2008-11-12 46 views
7

我有两个我需要在同一个可执行文件中访问的C DLL。我有两个库的头文件和.LIB文件。不幸的是,我需要访问的功能的子集具有完全相同的名称。到目前为止我所能想到的最好的解决方案是使用LoadLibrary加载其中一个DLL,并使用GetProcAddress显式调用它的方法。有没有办法让我隐式加载这两个库,并以某种方式给编译器提示,在一种情况下,我想调用DLL A中的OpenApi,另一种情况下,我想调用DLL B中的OpenApi?从两个不同的C DLL中调用两个具有相同名称的函数

我正在使用Visual Studio 2008和相应的C运行时库(msvcr90.dll)在C++中开发我的可执行文件。

[编辑]

评论者伊利亚下面问什么我不喜欢有关GetProcAddress的解决方案。我不喜欢它有两个原因:

  1. 它使代码更加复杂。一行调用函数的代码被三行代码替换,一行定义函数签名,一行调用GetProcAddress,另一行实际调用函数。
  2. 它更容易出现运行时错误。如果我拼错了函数名或弄乱了签名,我在运行时才看到错误。假设我决定整合一个新版本的dll,并且其中一个方法名称已经改变,它会编译得很好,直到实际调用GetProcAddress时才会出现问题,在测试阶段甚至可能会错过。

回答

4

它曾经是你可以使用链接器.def文件'重命名'导入的符号。您可能仍然可以,但自从.def文件被广泛使用以来已经很长时间了,很难找到文档。

当前的MSDN文档将IMPORTS指令列为'保留关键字'。我不确定这是否意味着他们删除了功能,或者他们只是不想再支持它。

这里的描述Imports指令页:

http://www.digitalmars.com/ctg/ctgDefFiles.html#imports

其他缺憾替代品:

  1. 创建包装函数冲突的API。这些功能可以做舞蹈LoadLibrary()/GetProcAddress()。所有其他非冲突函数都可以像平常一样隐式链接。实际上,这个解决方案可能是这个答案中最不起眼的3个。

  2. 创建2个包装器DLL,以便每个DLL仅链接到具有冲突名称的一个或另一个库。在包装器DLL中使用不同的名称,这些名称只是简化为真正的库。请注意,包装库不需要包装所有的API - 它们只需要包装冲突的包装。

1

在我对此事进行了一些更多的思考之后,我设法到达了Mike B的第二个替代品(或者如果您计算了原始建议,那么就是#3)。

这是我最喜欢的三个对于我的具体情况,因为它似乎需要最少的工作量,可能是最明显的破译给新的看代码的人。我相信,我可以请按照下列步骤,启动和运行:

  1. 使用一些正则表达式魔术和查找/替换打开头文件与函数调用,我有到一个包装头文件和一个包装的实现文件。 (在包装器DLL中的每个方法都通过一些常见的新元素与名称区分,节省了我不得不排除冲突的时间)因此,FunctionCall()在每个相应的包装器DLL中成为WrapperOneFunctionCall()和WrapperTwoFunctionCall()。
  2. 将包装DLL链接到其对应的基本DLL。
  3. 将我的可执行文件链接到包装器dll,删除基础dll的链接,但仍包括不需要从基本dll解析的常量,枚举和结构定义(因为我的包装函数仍然采用相同的参数类型)

如果有人仍然阅读此线程我的后续问题是:“这有什么不对的解决方案?”

非常感谢回复者的帮助。

+0

由于这是C++,因此您可能还会考虑使用名称空间来区分这两个函数,而不是以特殊用途的方式来修改函数名称,这些名称必须进一步解释。 缺点是这对于C语言调用者不起作用。 – orcmid 2008-11-13 04:10:09

相关问题