【发布时间】:2014-01-04 19:11:16
【问题描述】:
我正在努力增加对基本库链接、依赖项等的理解。我创建了一个包含三个项目的 Visual Studio 解决方案
静态
lib使用/MTd和单个类 (Foo),一种方法int GetNum() { return 5; }使用
/MDd与单个类 (Bar) 共享dll,一种方法int GetNum() { Foo f; return f.GetNum(); }Win32 控制台应用程序。那叫
Bar b; std::cout << b.GetNum() << std::endl
当我尝试构建它时,它抱怨找不到我的 dll 的关联库。做了一些研究,发现我需要将__declspec(dllexport) 添加到我的GetNum() 方法中,我会得到一个.lib。很酷。
接下来是控制台应用程序说它找不到Foo 的静态库。我将它添加到我的参考文献中,一切都构建并运行良好。
我的问题是 - 为什么我的 exe 需要了解有关 Foo 的任何信息?我想有效地将我所有的依赖项“烘焙”到 dll 中,这样我就可以分享它,链接到它,然后一切顺利。
这不是语言的工作方式还是我缺少的设置/模式?我的最终目标是能够构建一个 dll 来封装第三方 .lib 的使用,而不需要客户端应用程序担心添加对所有这些的引用。
更新
这是大部分代码。
// ---------------------- Lib (e.g. Foo)
#pragma once
class MathLib
{
public:
MathLib(void);
~MathLib(void);
int GetNum() { return 83; }
};
// ---------------------- DLL (e.g. Bar)
#pragma once
#ifdef CONSOLETEST_EXPORT
#define CONSOLETEST_API __declspec(dllexport)
#else
#define CONSOLETEST_API __declspec(dllimport)
#endif
#include "MathLib.h"
class MathDll
{
public:
__declspec(dllexport) MathDll(void);
__declspec(dllexport) ~MathDll(void);
__declspec(dllexport) int GetNumFromDyn()
{
MathLib m;
return m.GetNum();
}
};
// ---------------------- exe
int _tmain(int argc, _TCHAR* argv[])
{
MathDll m;
std::cout << "num is " << m.GetNumFromDyn() << std::endl;
return 0;
}
【问题讨论】:
-
您在包含在控制台应用程序中的 DLL 标头中是否有
Foo?给你看代码,否则很难说是怎么回事。 -
我确实有来自
Bar.h的#include "Foo.h",否则我应该如何将Foo 封装在Bar 中?我会更新代码。 -
看...这正是问题所在。你没有烘焙它。
Foo应该是Bar使用的实现细节,在你的情况下,它仍然存在于接口中,因为它明确包含在Bar中标题。我会写答案如何解决这个问题。等等。 -
注意:
/MT与/MD与 您 想要构建静态库还是动态库无关。这是how the C runtime library is linked 进入您的代码。对您拥有的所有 lib/dll 使用相同的设置!
标签: c++ visual-c++ dll compiler-construction linker