这个设计在DLL中初始化数组有什么问题吗?

Poo*_*ria 1 c++ constructor initialization reference dllexport

让我们假设我们有一个DLL,并且应该有一个全局存储在其中的数组将被导出,我们想要通过从文件中读取一些内容来初始化它,所以我个人发现自己别无他法它在一个结构中能够使用构造函数初始化:

struct Construction{
 public:
  Construction(){
   //do the initialization thing and read the needed data from the file
  }
  SomeType sTArray[100];
};

__declspec(dllexport) Construction obj();
Run Code Online (Sandbox Code Playgroud)

现在它将被使用,程序员可以初始化对它的引用,然后使用如下的引用:

SomeType (&arrayRef)[100]=obj.sTArray;
Run Code Online (Sandbox Code Playgroud)

现在你觉得我在任何情况下都错了吗?

Jon*_*Jon 5

是的,你在某些时候为自己设置了一个非常令人讨厌的惊喜.

  1. 全局对象构造函数在DLL的C运行时启动期间运行.
  2. C运行时启动代码在DLLMain期间运行.
  3. 在DLLMain期间,您持有DLL加载程序锁.
  4. 您的对象构造函数可能涉及调用加载其他系统DLL的Win32 api.
  5. 在已经持有DLL加载程序锁定的同时加载另一个DLL会导致进程快速死亡.

我建议您暂停初始化数组,直到第一次尝试访问它,这将要求您作为函数调用的结果间接公开数组:

struct Construction{
public:
  Construction() : bInit(false) {};
  SomeType* GetArray()
  {
    if(!bInit)
    {
      //do the initialization thing and read the needed data from the file
      bInit = true;
    }
    return sTArray;
  };
private:
  SomeType sTArray[100];
  bool bInit;
};

__declspec(dllexport) Construction obj();
Run Code Online (Sandbox Code Playgroud)

当然,这需要分成单独的头文件和实现文件.