隐式链接DLL问题

时间:2010-01-16 14:44:08

标签: c++ visual-studio-2008 dll

我开始使用隐式链接研究DLL。我真的不完全明白它是如何工作的。请纠正我错在哪里。  我无法编译下一个代码(3个模块):

MyLib.h

#ifdef MYLIBAPI

#else


#define MYLIBAPI extern "C" __declspec(dllimport)

#endif


MYLIBAPI int g_nResult;

MYLIBAPI int Add(int nLeft, int nRight);

据我所知,这是DLL的标题。 #define MYLIBAPI extern "C" __declspec(dllimport)意味着我们将在这里声明一些将在专用的.cpp文件中描述的函数/变量,并将包含在DLL中。

MyLibFile1.cpp

#include <windows.h>

#define MYLIBAPI extern "C" __declspec(dllexport)

#include "MyLib.h"

int g_nResult; 
int Add(int nLeft, int nRight) {
   g_nResult = nLeft + nRight;
   return(g_nResult);
}

所以,这显然是我们的函数实现的文件。这是DLL的一部分,对吗?

MyExeFile1.cpp

#include <windows.h>
#include <strsafe.h>
#include <stdlib.h>

#include "MyLib.h"

int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) {

   int nLeft = 10, nRight = 25;

   TCHAR sz[100];
   StringCchPrintf(sz, _countof(sz), TEXT("%d + %d = %d"),
      nLeft, nRight, Add(nLeft, nRight));
   MessageBox(NULL, sz, TEXT("Calculation"), MB_OK);

   StringCchPrintf(sz, _countof(sz),
      TEXT("The result from the last Add is: %d"), g_nResult);
   MessageBox(NULL, sz, TEXT("Last Result"), MB_OK);
   return(0);
}

因此,这是我们使用库中函数的可执行文件。  整件事情都行不通。我试图把这一切都放到一个目录中并立即编译。我首先尝试从前两个模块(成功)编译DLL,然后编译可执行文件(更改头文件的路径)。然而,这两次都导致了2次错误:

错误LNK2019:函数___ tmainCRTStartup中引用的未解析的外部符号_WinMain @ 16

\ Visual Studio 2008 \ Projects \ MyExeFile1 \ Debug \ MyExeFile1.exe:致命错误LNK1120:1个未解析的外部

这样做的正确方法是什么 - 我应该在代码中更改什么以及如何编译代码(我使用VS2008)?  感谢。

3 个答案:

答案 0 :(得分:1)

#include <tchar.h>解决链接器错误。

您的头文件应如下所示:

#ifdef BUILDING_DLL
#  define MYLIBAPI extern "C" __declspec(dllexport)
#else
#  define MYLIBAPI extern "C" __declspec(dllimport)
#endif

MYLIBAPI int __stdcall Add(int nLeft, int nRight);

在解决方案资源管理器,属性,C / C ++,预处理器,预处理器定义中右键单击DLL项目,添加“BUILDING_DLL”。重复发布配置。

您可以使用Dumpbin.exe / exports验证您的DLL是否正确导出了这些函数。

__declspec(dllimport)声明符并不是绝对必要的,但它确实使它更有效。 __stdcall属性也不是必需的,但它确实可以使用任何支持调用DLL导出的语言来使用你的DLL。

答案 1 :(得分:0)

在MyExeFile1.cpp中将_tWinMain更改为WinMain。它正在寻找你的入口点名为WinMain而不是_tWinMain,因此链接器抱怨它无法找到WinMain。

有一些项目设置可以确定入口点函数的名称,但我不确定哪一个需要_tWinMain。

修改 根据这篇文章,如果你包含tchar.h,_tWinMain是一个映射到WinMain的定义。link text

答案 2 :(得分:0)

它甚至可以编译吗?你不应该#include <tchar.h>使所有TCHAR类型和定义都有效吗?