C++ 如何使用提供的带有HPP头的DLL文件?

C++ 如何使用提供的带有HPP头的DLL文件?,c++,visual-studio,dll,C++,Visual Studio,Dll,我目前在尝试实现与Verifone PoS的集成时遇到了一些问题 与我们合作的银行为我们提供了一个.dll文件、一个.h文件和一个.hpp文件 我通常是一名Java或PHP开发人员,所以在过去的几天里,我在网上找到了关于DLL文件以及如何使用它们的所有信息,但到目前为止似乎没有一个是有效的。我得到了很多错误,其中许多是类似于“无效dll”的东西 我在网上发现,在dll文件旁边应该有一个.lib文件。我问过第三方,但显然 没有.lib文件。.dll文件包含集成所需的所有信息 从他们关于图书馆的文档

我目前在尝试实现与Verifone PoS的集成时遇到了一些问题

与我们合作的银行为我们提供了一个.dll文件、一个.h文件和一个.hpp文件

我通常是一名Java或PHP开发人员,所以在过去的几天里,我在网上找到了关于DLL文件以及如何使用它们的所有信息,但到目前为止似乎没有一个是有效的。我得到了很多错误,其中许多是类似于“无效dll”的东西

我在网上发现,在dll文件旁边应该有一个.lib文件。我问过第三方,但显然

没有.lib文件。.dll文件包含集成所需的所有信息

从他们关于图书馆的文档中,我发现:

提供的二进制文件的形式是一个动态库。就其性质而言,动态库允许更容易的更新和更正,而不需要重新编译或重新链接客户端(调用)代码,只要过程原型(函数参数和返回类型)保持不变

用于库实现的语言是C++ +< /P> 为了访问库二进制文件中实现的功能,提供了一个C风格的头接口。这包括可调用的函数原型以及需要解释返回数据的结果结构的类型,以便对先前访问的功能(特定请求的事务)有意义

是的,.h文件只包含数据类型,.hpp文件包含如下声明:

extern "C" __declspec(dllexport) bool doSomething(int param);
LIBRARY MyLibrary
EXPORTS
?AnotherFunction@@YAXH@Z
?SomeFunction@@YAXH@Z
在他们的文档中还有一个示例,说明了实现应该是什么样子的(而且相当简单):

看起来这些函数可以像那样简单地调用,但它们不能。如果我尝试这样做,我会得到一个“未定义函数”(或类似)错误

在这一点上,似乎唯一有效的方法(可能)是使用LoadLibrary函数加载DLL。但是,除了我尝试调用的任何函数,无论参数是什么,它都返回false之外,我根本不使用.hpp文件似乎有点错误

我们到了。我该怎么办?是否有方法加载DLL并将提供的HPP文件用作函数定义?如果没有,除了LoadLibrary+GetProcAddress组合之外,还有其他方法可以做到这一点吗

谢谢大家!

我假设dll是本机dll,而不是托管程序集(.net dll)

通常,dll作者会向生成系统添加预处理器定义,如
dll\u EXPORT
。因此,如果作者编译dll,导入库(一个小的.lib文件)将包含使用
dll\u API
宏的所有函数。然后作者可以将完全相同的标题发送给用户。由于该用户不需要定义
DLL\u导出
宏,
DLL\u API
将解析为dlliport,这基本上表示带注释的函数是在导入库中定义的

这样的头可能看起来像这样(整个
#if
条件通常在其自己的头文件中,然后包含在导出函数的所有头文件中):

如果作者构建项目(在msvc中),编译器将生成dll文件和一个小的.lib文件,即导入库。这个库基本上完成了您现在必须做的事情:调用
LoadLibrary
GetProcAddress
来解析用
\uu declspec(dllexport)
注释的所有函数

下面的部分有点推测,我在这里猜测一下

所有的
\uu declspec(dllimport)
都是告诉消费者这个dll包含这些函数。但是链接器必须将声明链接到它的定义(实现),因此函数必须在编译时的某个地方定义。那个地方就是导入库(.lib)。如果不链接导入库,则在生成项目时会出现链接器错误

这意味着简单地将
dllexport
更改为
dllimport
并不能解决您的问题。如果没有导入库,您唯一的选择就是使用
LoadLibrary
手动加载dll并搜索每个函数

如果我是你,我会要求作者提供一个使用dll的示例项目。另外,使用本机dll的唯一方法是链接到导入库或手动加载所有内容

从dll手动生成导入库 我已经测试过了,以确保它能正常工作

首先,修复头文件,要么像上面示例中那样使用宏,要么直接使用
dllimport

其次,打开VS的开发人员命令提示符,并按照answer中的步骤进行操作。确保使用正确的文件名和目标体系结构(x64或x86)。现在应该有一个.lib文件了

第三,将库添加到项目中

  • 添加库的目录(将其放置在靠近项目的位置,以便使用相对路径)。打开项目属性并按照此图像中的步骤操作: 确保配置和平台是正确的(您可能希望它如图所示)。也可以使用相对路径。单击“宏”按钮查看所有可用的预定义路径
  • 将库添加到链接器依赖项:
  • 将标题放在项目中可以访问的某个位置
  • 现在,您可以简单地在项目中的任何位置包含标题,并使用其中声明的函数。但是请注意,dll文件必须放在
    LoadLibrary
    可以找到它的地方。最好是项目的可执行文件所在的目录

    奖金事实 定义文件(.def)实际上非常简单。上面我的示例代码的def文件是:

    LIBRARY MyLibrary
    EXPORTS
    AnotherFunction
    SomeFunction
    
    如果我删除
    extern“C”
    b
    LIBRARY MyLibrary
    EXPORTS
    AnotherFunction
    SomeFunction
    
    LIBRARY MyLibrary
    EXPORTS
    ?AnotherFunction@@YAXH@Z
    ?SomeFunction@@YAXH@Z
    
    LIBRARY MyLibrary
    EXPORTS
    ?AnotherFunction@FooSpace@@YAXH@Z
    ?SomeFunction@FooSpace@@YAXH@Z