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