首页 > 解决方案 > C++ dll定义静态成员

问题描述

我正在迈出进入 DLL 的第一步,我正在尝试为链表编写一个类并将其导出到 .dll。当我尝试定义静态成员时,出现编译错误:

[错误] dllimport 类的静态数据成员 'dll::Container::IDcount' 的定义

这是我的代码:

容器.h

 #ifndef _CONTAINER_H_
 #define _CONTAINER_H_

 #if BUILDING_DLL
 #define DLLIMPORT __declspec(dllexport)
 #else
 #define DLLIMPORT __declspec(dllimport)
 #endif

 #define DEFAULT_SIZE 8

namespace dll{
 typedef union{
    char _c;
    short _s;
    int _i;
    long _l;
    float _f;
    double _d;
 }unit_t;

 typedef unsigned long long size_t;

 class DLLIMPORT Container{
    private:
        static size_t IDcount;
        unit_t* data;
        size_t size;
        size_t bytes;
        size_t memberID;
        Container *next;
        Container *prev;

    public:
        Container();
        Container(size_t size);
        Container(const Container &copy);
        ~Container();
 }; 
}

 #endif

容器.cpp

#include "container.h"

namespace dll{

 size_t Container::IDcount = 0;

 Container::Container(){
    this->memberID = 0;
    this->size = DEFAULT_SIZE;
    this->bytes = DEFAULT_SIZE * sizeof(unit_t);
    this->data = new unit_t[DEFAULT_SIZE];
    for(size_t i = 0; i < DEFAULT_SIZE; i++)
        this->data[i] = {0x0};
    this->next = nullptr;
    this->prev = nullptr;
 }

 Container::Container(size_t size)
    : size(size){
    this->memberID = 0;
    this->bytes = this->size * sizeof(unit_t);
    this->data = new unit_t[this->size];
    for(size_t i = 0; i < this->size; i++)
        this->data[i] = {0x0};
    this->next = nullptr;
    this->prev = nullptr;
 }

 Container::Container(const Container &copy){
    this->memberID = copy.memberID;
    this->size = copy.size;
    this->bytes = copy.bytes;
    this->data = new unit_t[this->size];
    for(size_t i = 0; i < this->size; i++)
        this->data[i] = copy.data[i];
    this->next = copy.next;
    this->prev = copy.prev;
 }

 Container::~Container(){
    for(size_t i = 0; i < this->size; i++)
        this->data[i]= {0x0};
    delete[] this->data;
    this->memberID = 0x0;
    this->size = 0x0;
    this->bytes = 0x0;
    if(!(this->prev))
        this->prev->next = this->next;      
    if(!(this->next))
        this->next->prev = this->prev;
    this->next = nullptr;
    this->prev = nullptr;
 }
}

我错过了什么吗?

提前致谢

标签: c++static-membersdllexport

解决方案


BUILDING_DLL宏定义不会进入编译器(即使Dev -C++已按定义显示)。下面是一个小示例,它将您的文件(没有更改)从cmdline构建为.dll(您可以忽略最后一部分,因为它是一个测试,看看它是否也可以使用VStudio构建)。

输出

e:\Work\Dev\StackOverflow\q050979671>set PATH=%PATH%;c:\Install\x64\MinGW32\MinGW32\7.2.0-posix-seh-rt_v5-rev1\mingw64\bin

e:\Work\Dev\StackOverflow\q050979671>dir /b
build.bat
container.cpp
container.h

e:\Work\Dev\StackOverflow\q050979671>g++ -shared -fPIC -DBUILDING_DLL=1 -std=c++11 -o container_g++.dll container.cpp

e:\Work\Dev\StackOverflow\q050979671>dir /b
build.bat
container.cpp
container.h
container_g++.dll

e:\Work\Dev\StackOverflow\q050979671>rem NOTE: "container_g++.dll" WAS CREATED

e:\Work\Dev\StackOverflow\q050979671>rem Building WITHOUT `-DBUILDING_DLL=1`

e:\Work\Dev\StackOverflow\q050979671>g++ -shared -fPIC -std=c++11 -o container_g++.dll container.cpp
container.cpp:5:20: warning: 'dll::Container::IDcount' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]
  size_t Container::IDcount = 0;
                    ^~~~~~~
container.cpp:7:2: warning: 'dll::Container::Container()' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]
  Container::Container(){
  ^~~~~~~~~
container.cpp:18:2: warning: 'dll::Container::Container(dll::size_t)' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]
  Container::Container(size_t size)
  ^~~~~~~~~
container.cpp:29:2: warning: 'dll::Container::Container(const dll::Container&)' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]
  Container::Container(const Container &copy){
  ^~~~~~~~~
container.cpp:40:2: warning: 'dll::Container::~Container()' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]
  Container::~Container(){
  ^~~~~~~~~
container.cpp:5:9: error: definition of static data member 'dll::Container::IDcount' of dllimport'd class
  size_t Container::IDcount = 0;
         ^~~~~~~~~

e:\Work\Dev\StackOverflow\q050979671>"c:\Install\x86\Microsoft\Visual Studio Community\2015\vc\vcvarsall.bat" amd64

e:\Work\Dev\StackOverflow\q050979671>cl /DBUILDING_DLL=1 container.cpp /MD /Focontainer_msvc.obj /link /dll /out:container_msvc.dll
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

container.cpp
Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:container_msvc.exe
/dll
/out:container_msvc.dll
container_msvc.obj
   Creating library container_msvc.lib and object container_msvc.exp

e:\Work\Dev\StackOverflow\q050979671>dir /b
build.bat
container.cpp
container.h
container_g++.dll
container_msvc.dll
container_msvc.exp
container_msvc.lib
container_msvc.obj

如所见,-DBUILDING_DLL=1

  • 传递它时,会构建.dll
  • 不通过的时候会弹出你遇到的错误

因为我没有Dev-C++,所以我不知道如何从它的选项中设置它(尽管我认为这很简单,比如去“工具 - >编译器选项”并选择“ C++ 编译器”然后添加宏定义),所以我将在代码级别启用它。
事情很简单,在container.cpp定义BUILDING_DLL 之前包含container.h,比如:

#define BUILDING_DLL 1
#include "container.h"

就个人而言,我更喜欢这种方法(而不是设置项目选项),因为它只需要完成一次,无论使用多少构建系统来构建代码。

运行失败的命令(上图),现在将生成.dll


推荐阅读