简体   繁体   English

VS2015行为dllexport / dllimport

[英]VS2015 behaviour dllexport/dllimport

Following problem popped up using VS2015: i wanted to make abstract base class, inherit another abstract class in own header, when the abstract inheritance is contained in own header the import/export macro seems to be interpreted wrong so the default constructor for the inheritance is not generated, i dont see it in .lib, additionally when using in an exe project link error occur. 使用VS2015出现以下问题:我想制作抽象基类,在自己的标头中继承另一个抽象类,当抽象继承包含在自己的标头中时,import / export宏似乎被解释为错误,因此该继承的默认构造函数为未生成,我在.lib中看不到它,此外,在exe项目中使用链接时会发生错误。

maybe i just have some problem of understanding... but for me it seems to be the definition of the api is correct in "TestDll.h" and wrong in "Inherited.h" 也许我只是有一些理解上的问题...但是对我来说,这似乎是在“ TestDll.h”中正确定义了api,在“ Inherited.h”中错误了定义

steps to reproduce: i made a project "TestDll" containg following headers including a define INHERITED_IN_SAME_HEADER to switch between inhertiance declaration in same or own header. 重现步骤:我制作了一个项目“ TestDll”,其中包含以下标头,包括一个定义的INHERITED_IN_SAME_HEADER,以在相同或自己标头中的继承声明之间进行切换。

header "testdll_api.h": 标头“ testdll_api.h”:

#pragma once
#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif

header "TestDll.h": 标头“ TestDll.h”:

// include export/import macros
#include "testdll_api.h"  
// define INHERITED_IN_SAME_HEADER to 1 to enable Inherited declaration in same header
// define INHERITED_IN_SAME_HEADER to 0 to enable Inherited declaration in own header Inherited.h
#define INHERITED_IN_SAME_HEADER 0

// abstract class containing default constructor and destructor
class TESTDLL_API CTestDll 
{
public:
    virtual void purevirt() = 0;
protected:
    CTestDll()
    {}
    virtual ~CTestDll()
    {}
};

// Inherited class in same header like CTestDll
// works
#if INHERITED_IN_SAME_HEADER
// another abstract class extending 
class TESTDLL_API Inherited : public CTestDll
{
public:
    virtual void purevirtInherited() = 0;
};
#endif

header "Inherited.h": 标头“ Inherited.h”:

#pragma once
#include "TestDll.h"
// strange here when following declaration is used intellisense (and potentially compiler) 
// see/uses TESTDLL_API as dllimport instead of dllexport ALTHOUGH WE ARE IN SAME PROJECT?!?!?
// note api definition is fetched indirectly from TestDLL.h which includes itself testdll_api.h
#if !INHERITED_IN_SAME_HEADER
class TESTDLL_API Inherited : public CTestDll
{
public:
    virtual void purevirtInherited() = 0;
};
#endif

in same solution i added console application "TestConsoleApplication", referencing "TestDll" project, with just following source: 在同一解决方案中,我添加了控制台应用程序“ TestConsoleApplication”,引用了“ TestDll”项目,并带有以下来源:

#include "stdafx.h"
#include "..\TestDll\Inherited.h"
class MyInheritedImpl : public Inherited
{
public:
    void purevirt()
    {}
    void purevirtInherited()
    {}
};
int main()
{
    MyInheritedImpl mimpl;

    return 0;
}

so when i define INHERITED_IN_SAME_HEADER to 1 i will get correct linking of console application, when defining INHERITED_IN_SAME_HEADER to 0 i get following errors: 因此,当我将INHERITED_IN_SAME_HEADER定义为1时,我将获得控制台应用程序的正确链接,而当将INHERITED_IN_SAME_HEADER定义为0时,我将得到以下错误:

1>------ Build started: Project: TestDll, Configuration: Debug Win32 ------
1>  TestDll.cpp
1>  TestDll.vcxproj -> c:\users\chris\documents\visual studio 2015\Projects\TestDll\Debug\TestDll.dll
2>------ Build started: Project: TestConsoleApplication, Configuration: Debug Win32 ------
2>  TestConsoleApplication.cpp
2>TestConsoleApplication.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall Inherited::Inherited(void)" (__imp_??0Inherited@@QAE@XZ) referenced in function "public: __thiscall MyInheritedImpl::MyInheritedImpl(void)" (??0MyInheritedImpl@@QAE@XZ)
2>TestConsoleApplication.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall Inherited::~Inherited(void)" (__imp_??1Inherited@@UAE@XZ) referenced in function "public: virtual __thiscall MyInheritedImpl::~MyInheritedImpl(void)" (??1MyInheritedImpl@@UAE@XZ)
2>c:\users\chris\documents\visual studio 2015\Projects\TestDll\Debug\TestConsoleApplication.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 1 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

This does not have anything to do with VS2015, it is just a simple mistake. 这与VS2015没有任何关系,只是一个简单的错误。 The problem is that your DLL project does not #include inherited.h, it only includes TestDll.h. 问题是您的DLL项目没有#includeInherited.h,而仅包含TestDll.h。 So your DLL cannot possibly export the Inherited class constructor and destructor, the compiler never saw their declaration. 因此,您的DLL可能无法导出Inherited类的构造函数和析构函数,因此编译器从未看到它们的声明。

But when you #include inherited.h in your test app, you claim that the class is imported from the DLL. 但是,当您在测试应用中#includeInherited.h时,您声称该类是从DLL导入的。 That's a lie, the DLL does not export it, the linker slaps you about the discrepancy since it cannot find the constructor and destructor you promised would be available. 这是一个谎言,DLL不会将其导出,链接器会把您的不符之处扑向您,因为它找不到您承诺的可用构造函数和析构函数。

You'll have to make up your mind about where this class needs to live. 您必须下定决心要上这堂课。 If you want it in the DLL then one of the DLL source files must #include inherited.h so the compiler sees __declspec(dllexport) and thus knows it needs to auto-generate the constructor and destructor and export them. 如果要在DLL中使用它,则DLL源文件之一必须 #includeInherited.h,以便编译器看到__declspec(dllexport),因此知道它需要自动生成构造函数和析构函数并导出它们。 If you want the client app to have the definition then you must delete TESTDLL_API from the class declaration. 如果希望客户端应用程序具有定义,则必须从类声明中删除TESTDLL_API。 Hard to imagine the latter is the intention, and it would be a breaking change from the way it was done before, it is however not wrong. 很难想象后者是目的,这与以前的方式相比将是一个重大变化,但这并不是错误的。

For Info: Hans has answered absolutly perfect, i now include headers at least once in the dll project, so the compiler can see my declaration and generate necessary exported constructor/destructor. 对于信息:Hans绝对完美地回答了这一点,我现在在dll项目中至少包含一次标头,因此编译器可以查看我的声明并生成必要的导出构造函数/析构函数。

it would be nice to be warned (i think only possible via IDE, intellisense) about such problem with something like "class Inherit gets nothing exported" i will suggest this at ms. 最好被警告(我认为只能通过IDE,intellisense实现)此类问题,例如“类继承不会导出任何内容”,我会在ms提出建议。

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

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