为什么GetProcAddress不起作用?

时间:2011-04-16 05:44:21

标签: c++ windows visual-studio winapi name-decoration

首先,我创建一个名为SimpleDll.dll的简单dll,其头文件为:

// SimpleDll.h
#ifdef MYLIBAPI
#else
#define MYLIBAPI __declspec(dllimport)
#endif

MYLIBAPI int Add(int a. int b);

其源代码:

// SimpleDll.c
#include <windows.h>

#define MYLIBAPI __declspec(dllexport)
#include "SimpleDll.h"    

int Add(int a, int b)
{
    return a + b;
}

然后我在另一个项目中调用它,它工作正常:

// TestSimpleDll.c
#include "stdafx.h"
#include <windows.h>
#include "SimpleDll.h"

#pragma comment(lib, "SimpleDll.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    printf("%d", Add(10, 30));    // Give the expected result 40
    return 0;
}

然而,当我致电GetProcAddress来获取它的地址时,它不起作用!

// TestSimpleDll2.c
#include "stdafx.h"
#include <windows.h>
#include "SimpleDll.h"

#pragma comment(lib, "SimpleDll.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    printf("%d", Add(10, 30));    // Give the expected result 40
    HMODULE hModule = GetModuleHandleA("SimpleDll.dll");    // hModule is found
    PROC add_proc       = GetProcAddress(hModule, "Add");     // but Add is not found !
    //  add_proc is NULL!
    return 0;
}

感谢您的帮助。 (PS:我在Windows7上使用VS2010)
更新:
这就是依赖步行者为SimpleDll.dll文件显示的内容:

enter image description here

2 个答案:

答案 0 :(得分:5)

如果要导出GetProcAddress的名称,则应使用.def文件。否则你将不得不处理c ++名称mangling和符号装饰。

您可以通过将函数声明为extern "C"来避免修改,但避免装饰的唯一方法是使用.DEF文件。

还有一件事 - 在Dependency walker中 - 使用F10在装饰和未装饰的名称之间切换。

答案 1 :(得分:2)

Dependency Walker是解决此类DLL问题的绝佳工具。

我假设您正在将DLL编译为C代码。否则,C ++会执行会导致问题的名称修改。

为了避免名称错误,只需将导出定义包装在extern“C”中。

extern "C" {
    MYLIBAPI int Add(int a. int b);
}