在工作中,我们使用一种品牌的电池循环器,它具有专有的编码数据格式,我希望直接在我的脚本中读取它,而不是使用数据的更大ASCII版本。制造商提供了一个DLL(没有库或头文件),以及一些Delphi示例代码的使用,非常少的文档和一个示例可执行文件(无法运行,出现错误0xc000007b)。 按照此教程,我成功创建了.lib并将我的VS2018项目与DLL链接。
使用以下代码,我可以调用DLL中所需的一个函数:
#pragma comment(lib, "MacReadDataFileLIB.lib")
#include <string>
extern "C" int OpenDataFile(const char*);
int main()
{
std::string path = "K:\\Testfile.036";
auto test = OpenDataFile(path.c_str());
}
当我逐步执行代码时,函数返回-1001,即失败并抛出异常。
运行时检查失败#0-ESP的值在函数调用中未正确保存。这通常是由于使用不同调用约定声明的函数指针调用声明为一种调用约定的函数而导致的。
从文档中我知道使用了stdcall
。
来自文档的其他相关信息:
使用OpenDataFile打开Maccor数据文件并返回一个句柄。如果句柄大于或等于0,则文件成功打开。 (...) 由于通常需要读取整个数据文件,因此有一个具有双重目的的函数LoadAndGetNextTimeData,用于加载时间数据并获取/返回最常见的数据。 所有函数至少需要通过OpenDataFile返回的句柄。 (...) 要读取数据,请反复调用LoadAndGetNextTimeData,直到它返回0为止。 最后,必须使用CloseDataFile关闭文件以释放分配的内存。function OpenDataFile(FileName: PChar): int32; function LoadAndGetNextTimeData(Handle: int32; PTimeData: pointer): int32; procedure CloseDataFile(Handle: int32);
extern "C" int __stdcall OpenDataFile(const char*);
它无法编译,出现了两个错误代码:
LNK1120 1个未解决的外部
LNK2019 未解决的外部符号_OpenDataFile@4在函数_main中被引用
我知道这是由于C++名称混淆导致的,但此时我卡住了。
GetProcAddress
(和LoadLibrary
)。 这将告诉您如何获取 DLL 中函数的地址,而与其调用签名无关。 然后,您可以通过适当声明的函数指针调用它,并以这种方式使其正常工作。 - Paul Sanders