我是C ++的新手,首先创建一个简单的dll和控制台应用程序来测试dll
。之后,dll
插件应可在x86机器(诊断工具,ECU或PLC)上工作。我得到的结构相同的示例将dll函数导出为__sdcall。所以我的helloWorld项目看起来像:
plugin.dll
-----------
plugin.h
#pragma once
#include "types.h"
#define EXPORT extern "C" __declspec (dllexport)
EXPORT S32 WINAPI Greetings(string *str);
plugin.cpp
#include "plugin.h"
#include "types.h"
S32 __stdcall Greetings(string *str){*str = "Hello From Plugin!"; return -1;}
和控制台应用程序看起来像:(两者在同一解决方案中,project/properties/cc++/adnvances/callingConvention = __cdecl (/Gd)
)
VS设置-解决方案配置=调试,解决方案平台= x86
main.cpp
HMODULE DllHandler = ::LoadLibrary(L"plugin.dll");
string greetingText;
typedef U32(*Type)(string*);
Type greetings = reinterpret_cast<Type>(GetProcAddress(DllHandler, "Greetings"));
greetings(&greetingText);
cout << greetingText << endl;
现在,在没有plugin.def
的情况下,GetProcAddress(DllHandler, "Greetings")
使用plugin.def返回null(0x000000)(与EXPORT一起),我得到装饰为Greetings
的{{1}},呼叫将成功但获得
运行时检查失败#0-在整个函数调用中ESP的值未正确保存。这通常是由于使用一种调用约定声明的函数和使用另一种调用约定声明的函数指针进行调用的结果。
也不允许使用命名约定进行强制转换。
我撰写了许多有关plugin.dll!Greetings@4
__cdecl
的帖子,但主要解释了清理堆栈或使用__stdcall
或.def
进行导出的组装级别。
我完全迷失了使用C ++的命名约定和处理方式。是与本地项目设置有关,还是该dll将在所有环境中运行?特别是在这个示例项目中,我应该如何处理?