5

这是我的 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;
}

因此,我的 LIB.dll 使用 成功加载LoadLibrary(),但GetProcAddress()失败并显示 127。这似乎是因为它没有找到我的函数名称,但我不明白为什么会失败。

非常感谢您的帮助!:) ~P

4

5 回答 5

5

由于该标记是 C++,因此您需要C为函数声明一个名称:

extern "C" int sysLol(char *arg);

您可以使用Dependency Walker查看编译器为您的 C++ 函数提供的实际名称。

成功后,将函数转换为 GetProcAddress 返回的指针到实际函数类型:

typedef int (*sysLol_t)(char *arg);
sysLol_t pFunc = GetProcAddress(e,"sysLol");
于 2014-09-16T20:32:33.793 回答
2

ERROR_PROC_NOT_FOUND意味着没有具有该名称的导出函数。

没什么好说的了。也许你把名字弄错了。这可能是字母大小写的简单不匹配。可能 DLL 构建不正确并且没有导出函数。也许 DLL 正在修饰或修改名称。当然,从问题中的代码来看,没有证据表明您试图导出该函数,或者确实抑制了装饰/修改。

使用dumpbinDependency Walker 之类的工具来检查导出的函数的名称。这可能会对问题有所启发。

与在运行时链接LoadLibraryand相比GetProcAddress,在加载时链接要方便得多。使用构建 DLL 时生成的 .lib 导入库来执行此操作。

还值得指出的是调用约定不匹配。您在 DLL 端有 cdecl,在可执行端有 stdcall。并且不要将指针投射到DWORD. 当你编译为 64 位时,结果很糟糕。

于 2014-09-16T20:09:14.223 回答
1

符号必须从 Windows DLL 显式导出。将您的函数声明为__declspec(dllexport)或将 DEF 文件传递​​给链接器以指示它导出您的函数。请参阅此说明dllexport

于 2014-09-16T20:48:01.307 回答
1

请使用 Dependancy Walker,它会提示在 dll 中注册的方法名称。

http://www.dependencywalker.com/

如果方法名称是- getNumber Dependency Walker 将显示实际的方法名称为-_Z9GetNumberd

前任 -

lpGetNumber = (LPGETNUMBER)GetProcAddress(hDLL, "_Z9GetNumberd");

现在LoadLibraryGetProcAddress()两者都将起作用。

于 2019-04-05T12:36:10.877 回答
0

使用 DependencyWalker,您可以查看已装饰/未装饰的函数(查看->未装饰 C++ 函数)

尝试使用修饰函数名称形式调用 GetProcAddress。

于 2021-11-07T13:38:11.930 回答