我是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
)。我需要一些需要从MyExe
和MyImplementations
访问的辅助类,因此MyUtils
。我希望这个帮助程序类可以静态使用,但它不是强制性的。
在我开始使用MyUtils
类添加HelperC
之前,我有一个编译版本。我必须使用__declspec(dllexport)
标记界面析构函数,以及DoSomething
方法。我还必须标记ImplementationB
的构造函数,以便从MyExe
实例化它,这是有道理的。但是,当我尝试使用__declspec(dllexport)
标记整个类(实现和接口)时,该示例将无法编译( 有意义)。
从我读过的内容来看,在dll中使用静态字段并使用外部代码中的静态字段并没有真正起作用。因此,作为替代方案,我使Foobar
非静态并将HelperC
实例传递给方法,如InterfaceA
所述。由于我已经有了简单的课程,我认为这应该也可以。但是,现在编译器在ImplementationB
(LNK2019)的构造函数上抛出错误。
简而言之:我在与我的更改无关的部分中发现链接错误,并且有一些小文档描述了我需要执行的具体步骤才能获得简单的dll参考工作。
有人可以指出我需要添加什么以及我需要添加它以使其编译?此外,有些人对C ++ dll引用不做什么并且没有帮助(例如,不要在项目中使用静态)。
答案 0 :(得分:0)
经过多次挖掘,我发现罪魁祸首是一个神奇的项目设置。它名为Ignore Import Library
,位于Project Properties->Linker->General
,默认设置为Yes
,大多数情况下应设置为No
。该设置告诉可执行项目在编译期间使用dll的lib文件。这听起来仍然很奇怪(听起来像重复的构建输出),但据我所知,lib文件描述如何链接到dll。如果您的dll在构建期间生成了lib,则可能需要将设置设置为No
。
我还了解到,为了能够将HelperC
类用作静态可访问的帮助程序,我需要将dllimport
与macro trick结合使用,如@drescherjm所述。只需要dllimport
声明就可以跨库使用数据成员(静态类字段或全局定义的变量)。它也可以应用于函数,虽然它不是必需的,在这种情况下,它在库链接期间提供了轻微的性能提升。
为了完整性,我的项目结构在开始工作之后:
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 ++类库项目,则可能需要将Project Properties->Debugging->Debugger Type
设置翻转为Mixed
,然后才能设置/使用断点DLL代码。请参阅this。
我希望这可以帮助那些在C ++(和Visual Studio)中与dll进行摔跤的人。