已引发异常Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.出现异常的原因可能是函数调用约定不一致导致的。在Windows平台上,默认的函数调用约定是__cdecl,但是有些DLL可能使用了不同的调用约定,比如__stdcall。因此,在使用函数指针时,需要确保函数指针的声明与DLL中函数的调用约定一致。
咱们这里将函数指针的声明改为__stdcall调用约定。在加载DLL时也要相应地使用GetProcAddress。
注意下文件命名,写在首行注释里了
[C++] 纯文本查看 复制代码 // 头文件 NaturalCardWrapper.h
#ifndef NATURALCARDWRAPPER_H
#define NATURALCARDWRAPPER_H
#include <Windows.h>
// 函数指针类型定义,使用__stdcall调用约定
typedef long (__stdcall *DeviceOpenFunc)(char);
// 加载DLL并获取函数地址
DeviceOpenFunc LoadAndGetDeviceOpenFunc();
// 释放DLL
void FreeDeviceOpenFunc(HMODULE hDLL);
#endif // NATURALCARDWRAPPER_H
[C++] 纯文本查看 复制代码 // 源文件 NaturalCardWrapper.cpp
#include <iostream>
#include <Windows.h>
#include "NaturalCardWrapper.h"
// 加载DLL并获取device_Open函数的地址
DeviceOpenFunc LoadAndGetDeviceOpenFunc() {
// 加载DLL
HMODULE hDLL = LoadLibraryA("NaturalCard.dll");
if (hDLL == nullptr) {
std::cerr << "Error loading DLL: NaturalCard.dll" << std::endl;
return nullptr;
}
// 获取device_Open函数的地址
DeviceOpenFunc deviceOpenFunc = (DeviceOpenFunc)GetProcAddress(hDLL, "device_Open");
if (deviceOpenFunc == nullptr) {
std::cerr << "Error getting function address: device_Open" << std::endl;
FreeLibrary(hDLL);
return nullptr;
}
return deviceOpenFunc;
}
// 释放DLL
void FreeDeviceOpenFunc(HMODULE hDLL) {
FreeLibrary(hDLL);
}
int main() {
// 加载DLL并获取device_Open函数的地址
DeviceOpenFunc deviceOpen = LoadAndGetDeviceOpenFunc();
if (deviceOpen == nullptr) {
std::cerr << "Failed to load and get function address." << std::endl;
return 1;
}
// 调用device_Open函数
const char* szPort = "COM1"; // 替换为你的端口号
long status = deviceOpen(const_cast<char*>(szPort));
// 检查返回值
if (status == 0) {
std::cout << "Device successfully opened on port: " << szPort << std::endl;
} else {
std::cout << "Failed to open device on port: " << szPort
<< ", error code: " << status << std::endl;
}
// 释放DLL
HMODULE hDLL = GetModuleHandleA("NaturalCard.dll");
if (hDLL) {
FreeDeviceOpenFunc(hDLL);
}
return 0;
}
|