这是我的DLL代码:
#include <Windows.h>
#include <iostream>
int sysLol(char *arg);
int sysLol(char *arg)
{
std::cout<<arg<<"\n";
return 1;
}
这是我的应用程序代码:
#include <Windows.h>
#include <iostream>
#include <TlHelp32.h>
#include <stdlib.h>
typedef int (WINAPI* Lol)(char* argv);
struct PARAMETERS
{
DWORD Lol;
};
int main()
{
PARAMETERS testData;
HMODULE e = LoadLibrary(L"LIB.dll"); //This executes without problem
if (!e) std::cout<<"LOADLIBRARY: "<<GetLastError()<<"\n";
else std::cout<<"LOADLIBRARY: "<<e<<"\n";
testData.Lol = (DWORD)GetProcAddress(e,"sysLol"); //Error 127?
if (!testData.Lol) std::cout<<testData.Lol<<" "<<GetLastError()<<"\n";
else std::cout<<"MESSAGEBOX: "<<testData.Lol<<"\n";
std::cin.ignore();
return 1;
}
因此,使用LoadLibrary()
成功加载了我的LIB.dll,但GetProcAddress()
失败了127。
这似乎是因为它没有找到我的函数名称,但我不明白为什么会失败。
非常感谢帮助! :) 〜P
答案 0 :(得分:3)
由于该标记是C ++,因此您需要为该函数声明C
名称:
extern "C" int sysLol(char *arg);
您可以看到编译器使用Dependency Walker为您的C ++函数指定的实际名称。
成功后,将函数转换为GetProcAddress返回的指针到实际的函数类型:
typedef int (*sysLol_t)(char *arg);
sysLol_t pFunc = GetProcAddress(e,"sysLol");
答案 1 :(得分:1)
即ERROR_PROC_NOT_FOUND
,这意味着没有具有该名称的导出函数。
没有更多要说的了。也许你的名字错了。这可能是一个简单的字母错配。可能DLL已错误构建,并且未导出该函数。也许DLL正在装饰或破坏名称。当然,从问题中的代码来看,没有证据表明你试图导出函数,或者确实压制了装饰/修改。
使用dumpbin
或Dependency Walker等工具检查导出函数的名称。这可能会解决这个问题。
在运行时与LoadLibrary
和GetProcAddress
链接,而不是在加载时链接更方便。使用构建DLL时生成的.lib导入库来执行此操作。
值得指出的是调用约定不匹配。你在DLL端有cdecl,在可执行端有stdcall。并且不要指向DWORD
。当你编译64位时,这会很糟糕。
答案 2 :(得分:0)
必须从Windows DLL显式导出符号。将您的函数声明为__declspec(dllexport)
或将DEF文件传递给链接器以指示它导出您的函数。见this description of dllexport
.
答案 3 :(得分:0)
请使用Dependancy Walker,它将提示有关在dll中注册的方法名称的提示。
http://www.dependencywalker.com/
如果方法名称为- getNumber
Dependency Walker会将实际的方法名称显示为-_Z9GetNumberd
Ex-
lpGetNumber = (LPGETNUMBER)GetProcAddress(hDLL, "_Z9GetNumberd");
现在LoadLibrary
和GetProcAddress()
都可以使用。