如何在 C++ 中设置多项目解决方案?
How do I set up a multi-project solution in C++?
我是 C++ 的新手,我很难让我的 dll 引用正常工作。几天来我一直在努力让它工作,但我发现的一些解释经常提到做 x 或 y,但不要告诉我 如何做 x 或 y。由于我不是 C++ 老手,我需要有人指导我完成它。我想要做的是:
MySolution
MyExe (Win32 .exe)
Main.h
Main.cpp
(constructs ImplementationB calls the methods as defined by InterfaceA, then deletes the instances)
(calls/fills HelperC.Foobar)
MyInterfaces (dll)
InterfaceA.h
~InterfaceA();
virtual void DoSomething();
MyUtils (dll)
HelperC.h
static float Foobar;
HelperD.cpp
float HelperC::Foobar = 1.0f;
MyImplementations (dll)
ImplementationB : InterfaceA
(uses the value from HelperC.Foobar)
MyExe
和 MyImplementations
项目包含大部分执行代码。但是,我需要一个界面,所以我需要一个界面项目(MyInterfaces
)。我需要一些助手 classes 需要可以从 MyExe
和 MyImplementations
访问,因此 MyUtils
。我希望这个助手 class 是静态可用的,尽管它不是强制性的。
在开始添加 MyUtils
和 HelperC
class 之前,我有一个编译版本。 我不得不用__declspec(dllexport)
,以及 DoSomething
方法。我还必须标记 ImplementationB
的构造函数以便从 MyExe
实例化它,这是有道理的。但是,当我尝试用 __declspec(dllexport)
标记整个 class(实现和接口)时,该示例无法编译(not 使感)。
根据我的阅读,在 dll 中包含静态字段并从外部代码中使用它们并不能很好地工作。因此,作为替代方案,我将 Foobar
设为非静态,并将 HelperC
实例传递给 InterfaceA
所描述的方法。因为我已经得到了简单的 classes 来工作,所以我认为它也应该可以工作。但是,现在编译器在 ImplementationB
(LNK2019).
的构造函数上抛出错误
简而言之:我在与我的更改无关的部分到处都遇到 link 错误,并且几乎没有文档描述我需要执行的具体步骤才能获得简单的 dll 参考工作。
有人可以指出我需要添加什么以及需要添加到哪里才能编译吗?此外,一些关于 C++ dll 引用的注意事项会有很大帮助(例如,不要跨项目使用静态)。
经过多方挖掘,我发现罪魁祸首是一个神奇的项目设置。它被称为Ignore Import Library
,位于Project Properties->Linker->General
,默认设置为Yes
,但在大多数情况下应设置为No
。该设置告诉可执行项目在编译期间使用 dll 的 lib 文件。这对我来说仍然听起来很奇怪(听起来像是重复的构建输出),但据我了解,lib 文件描述了 how 到 link 到 dll。如果您的 dll 在构建期间生成一个库,您可能希望将设置设置为 No
.
我还了解到,为了能够将 HelperC
class 用作静态可访问的助手,我需要将 dllimport
与 macro trick 结合使用,如@drescherjm 所述。 dllimport
声明只需要能够跨库使用数据成员(静态 class 字段或全局定义的变量)。它也可以应用于函数,但不是必需的,在这种情况下,它会在库 linking.
期间提供轻微的性能提升
为了完整起见,我的项目结构在运行后:
MySolution
MyExe (Win32 .exe, Debugger Type=Mixed)
Main.h
Main.cpp
(constructs ImplementationB calls the methods as defined by InterfaceA, then deletes the instances)
(calls/fills HelperC::Foobar)
MyInterfaces (dll, Ignore Import Library=Yes, because there is no .lib after building)
InterfaceA.h
class __declspec(dllexport) InterfaceA
~InterfaceA() {};
virtual void DoSomething() = 0;
MyUtils (dll, Ignore Import Library=No)
HelperC.h
class __declspec(dllimport/dllexport) HelperC // (see macro trick)
static float Foobar;
HelperD.cpp
float HelperC::Foobar = 1.0f;
MyImplementations (dll, Ignore Import Library=No)
ImplementationB.h
class __declspec(dllexport) ImplementationB : public InterfaceA
ImplementationB();
~ImplementationB();
void DoSomething();
ImplementationB.cpp
ImplementationB::ImplementationB() {};
ImplementationB::~ImplementationB() {};
ImplementationB::DoSomething() { /* Omitted */ };
(uses HelperC::Foobar in implementation)
附带说明:如果您在 Visual Studio 中添加了默认的 C++ class 库项目,您可能需要先将 Project Properties->Debugging->Debugger Type
设置翻转为 Mixed
就能在dll代码中set/use断点。参见 this。
我希望这能帮助那些正在使用 C++(和 Visual Studio)处理 dll 的其他人。
我是 C++ 的新手,我很难让我的 dll 引用正常工作。几天来我一直在努力让它工作,但我发现的一些解释经常提到做 x 或 y,但不要告诉我 如何做 x 或 y。由于我不是 C++ 老手,我需要有人指导我完成它。我想要做的是:
MySolution
MyExe (Win32 .exe)
Main.h
Main.cpp
(constructs ImplementationB calls the methods as defined by InterfaceA, then deletes the instances)
(calls/fills HelperC.Foobar)
MyInterfaces (dll)
InterfaceA.h
~InterfaceA();
virtual void DoSomething();
MyUtils (dll)
HelperC.h
static float Foobar;
HelperD.cpp
float HelperC::Foobar = 1.0f;
MyImplementations (dll)
ImplementationB : InterfaceA
(uses the value from HelperC.Foobar)
MyExe
和 MyImplementations
项目包含大部分执行代码。但是,我需要一个界面,所以我需要一个界面项目(MyInterfaces
)。我需要一些助手 classes 需要可以从 MyExe
和 MyImplementations
访问,因此 MyUtils
。我希望这个助手 class 是静态可用的,尽管它不是强制性的。
在开始添加 MyUtils
和 HelperC
class 之前,我有一个编译版本。 我不得不用__declspec(dllexport)
,以及 DoSomething
方法。我还必须标记 ImplementationB
的构造函数以便从 MyExe
实例化它,这是有道理的。但是,当我尝试用 __declspec(dllexport)
标记整个 class(实现和接口)时,该示例无法编译(not 使感)。
根据我的阅读,在 dll 中包含静态字段并从外部代码中使用它们并不能很好地工作。因此,作为替代方案,我将 Foobar
设为非静态,并将 HelperC
实例传递给 InterfaceA
所描述的方法。因为我已经得到了简单的 classes 来工作,所以我认为它也应该可以工作。但是,现在编译器在 ImplementationB
(LNK2019).
简而言之:我在与我的更改无关的部分到处都遇到 link 错误,并且几乎没有文档描述我需要执行的具体步骤才能获得简单的 dll 参考工作。
有人可以指出我需要添加什么以及需要添加到哪里才能编译吗?此外,一些关于 C++ dll 引用的注意事项会有很大帮助(例如,不要跨项目使用静态)。
经过多方挖掘,我发现罪魁祸首是一个神奇的项目设置。它被称为Ignore Import Library
,位于Project Properties->Linker->General
,默认设置为Yes
,但在大多数情况下应设置为No
。该设置告诉可执行项目在编译期间使用 dll 的 lib 文件。这对我来说仍然听起来很奇怪(听起来像是重复的构建输出),但据我了解,lib 文件描述了 how 到 link 到 dll。如果您的 dll 在构建期间生成一个库,您可能希望将设置设置为 No
.
我还了解到,为了能够将 HelperC
class 用作静态可访问的助手,我需要将 dllimport
与 macro trick 结合使用,如@drescherjm 所述。 dllimport
声明只需要能够跨库使用数据成员(静态 class 字段或全局定义的变量)。它也可以应用于函数,但不是必需的,在这种情况下,它会在库 linking.
为了完整起见,我的项目结构在运行后:
MySolution
MyExe (Win32 .exe, Debugger Type=Mixed)
Main.h
Main.cpp
(constructs ImplementationB calls the methods as defined by InterfaceA, then deletes the instances)
(calls/fills HelperC::Foobar)
MyInterfaces (dll, Ignore Import Library=Yes, because there is no .lib after building)
InterfaceA.h
class __declspec(dllexport) InterfaceA
~InterfaceA() {};
virtual void DoSomething() = 0;
MyUtils (dll, Ignore Import Library=No)
HelperC.h
class __declspec(dllimport/dllexport) HelperC // (see macro trick)
static float Foobar;
HelperD.cpp
float HelperC::Foobar = 1.0f;
MyImplementations (dll, Ignore Import Library=No)
ImplementationB.h
class __declspec(dllexport) ImplementationB : public InterfaceA
ImplementationB();
~ImplementationB();
void DoSomething();
ImplementationB.cpp
ImplementationB::ImplementationB() {};
ImplementationB::~ImplementationB() {};
ImplementationB::DoSomething() { /* Omitted */ };
(uses HelperC::Foobar in implementation)
附带说明:如果您在 Visual Studio 中添加了默认的 C++ class 库项目,您可能需要先将 Project Properties->Debugging->Debugger Type
设置翻转为 Mixed
就能在dll代码中set/use断点。参见 this。
我希望这能帮助那些正在使用 C++(和 Visual Studio)处理 dll 的其他人。