5

首先,我创建了一个名为 的简单 dll SimpleDll.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内容:

在此处输入图像描述

4

2 回答 2

5

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

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

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

于 2011-04-16T06:16:04.317 回答
2

Dependency Walker是解决此类 DLL 问题的出色工具。

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

为了避免名称混淆,只需将导出定义包装在 extern "C" 中。

extern "C" {
    MYLIBAPI int Add(int a. int b);
}
于 2011-04-16T05:51:49.557 回答