c++ - 这种在 DLL 中初始化数组的设计有什么问题吗?

标签 c++ constructor reference initialization 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();

现在要使用它的地方,程序员可以初始化对它的引用,然后像下面这样使用该引用:

SomeType (&arrayRef)[100]=obj.sTArray;

现在你会认为我在任何情况下都是错的吗?

最佳答案

是的,您已经为自己设置了一个非常讨厌的惊喜。

  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();

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

关于c++ - 这种在 DLL 中初始化数组的设计有什么问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4314990/

相关文章:

php - 函数内部的静态变量不能保存对单例的引用

c++ - 动态对象初始化 C++

c++ - 执行类的成员函数

c++ - 如何在不使用循环或迭代器的情况下检查所有列表元素并在满足条件时删除一个

c++ - 我应该使用 shared_ptr<Object> myObject = (shared_ptr<Object>) new Object() 来访问私有(private)构造函数吗?

c++ - "Override"构造函数并调用祖 parent 构造函数

c++ - 按值返回的变量的相同地址

c++ - Qt 所见即所得 - 字体大小问题

javascript - 显示对象的对象对象问题

php - 用需要相互引用的记录填充两个表的最佳方法是什么?