繁体   English   中英

如何在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)

MyExeMyImplementations项目包含大多数执行代码。 但是,我需要一个接口,所以我需要一个接口项目( MyInterfaces )。 我需要一些可以从MyExeMyImplementations访问的帮助程序类,因此需要MyUtils 我希望此帮助程序类是静态可用的,尽管它不是强制性的。

在开始使用HelperC类添加MyUtils之前,我有一个编译版本。 我必须用__declspec(dllexport)以及DoSomething方法标记接口析构函数。 为了从MyExe实例化它,我还必须标记ImplementationB的构造函数。 但是,当我尝试使用__declspec(dllexport)标记整个类(实现和接口)时,该示例将无法编译( 没有意义)。

根据我的阅读,在dll中具有静态字段并从外部代码中使用它们并不能很好地工作。 因此,作为替代方案,我使Foobar非静态的,并将HelperC实例传递给InterfaceA描述的方法。 由于我已经上过简单的课,因此我认为它也应该工作。 但是,现在编译器在ImplementationB (LNK2019)的构造函数上引发错误。

简而言之:我的节中到处都有链接错误,这些错误与我的更改无关,并且几乎没有文档描述我需要执行的特定步骤才能获得简单的dll引用。
有人可以指出我需要添加什么以及在哪里添加它才能进行编译吗? 另外,关于C ++ dll引用的一些注意事项会有所帮助(例如,不要在项目之间使用静态变量)。

经过大量挖掘,我发现罪魁祸首是一个神奇的项目环境。 它称为“ Ignore Import Library ,位于“ Project Properties->Linker->General Yes ,默认情况下设置为“ Yes ,而在大多数情况下应设置为“ No 该设置告诉可执行项目在编译过程中使用dll的lib文件。 这对我来说仍然听起来很奇怪(听起来像重复的生成输出),但是据我了解,lib文件描述了如何链接到dll。 如果您的dll在生成过程中生成了一个lib,则可能要将设置设置为No

我还了解到,要能够将HelperC类用作静态可访问的帮助程序,我需要将dllimport宏技巧结合使用,如@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代码中设置/使用断点。 。 看到这个

我希望这对在C ++(和Visual Studio)中使用dll的其他人有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM