【问题标题】:globals broken with alchemy?炼金术破坏了全局?
【发布时间】:2010-11-12 23:17:55
【问题描述】:

Adobe Alchemy 似乎没有运行全局构造函数。下面是一些简单的测试代码:

#include <stdio.h>

class TestClass {
public:
    TestClass(const char message[]) {
        printf("hello %s \n", message);
    }
};

TestClass global("global");

int main(int argc, char **argv) {
    TestClass local("local");
    printf("in main\n");
    return 0;
}

当使用原生 gcc 编译时,它会输出:

hello global
hello local
in main

当使用 alchemy gcc 编译时,它会输出:

hello local
in main

这个问题会破坏很多代码,尤其是 UnitTest++(这取决于初始化全局变量以使其自动测试列表功能正常工作)。

我真的很想弄清楚这一点。它是一个错误还是一个没有及时实现发布的功能?有办法解决吗?

编辑:Adobe 论坛上的相关帖子是here

【问题讨论】:

    标签: flash alchemy


    【解决方案1】:

    我遇到了同样的问题。据我所知,情况似乎是这样的:

    即使单个类在其初始化期间的任何时候尝试动态分配,每个类类型的静态和全局变量都将静默初始化失败。大概这是因为 ByteBuffer 用于动态内存尚不可用。我希望 Alchemy 的错误消息更清楚,因为目前它就像一串老式圣诞灯,一个死灯会导致整个灯串关闭。

    作为一种解决方法,一旦您发现了有问题的对象,您需要以某种方式将其初始化推迟到运行时。想到的三种技术是指针、惰性求值函数或对使用placement new 初始化的缓冲区的引用。

    指针

    // `global` is now a pointer
    TestClass *global;
    
    // all global variable initialization is found here now
    void init_globals() {
      global = new TestClass("global");
    }
    
    int main(int argc, char **argv) {
      // this needs to be explicitly called at the start Alchemy
      init_globals();
    

    然后您需要重构代码,将每次出现的global 更改为(*global)

    功能

    // `global` is now a function
    TestClass& global() {
      // static locals are initialized when their functions are first called
      static TestClass global_("global");
      return global_;
    }
    

    现在您需要将每次出现的global 替换为global()。值得注意的是,这是这三种技术中唯一一种不需要明确的init_globals 调用的技术。我推荐这种方式,除非由于某种原因将名称更改为global() 很麻烦......在这种情况下:

    放置新

    // a memory buffer is created large enough to hold a TestClass object
    unsigned char global_mem[sizeof(TestClass)];
    // `global` is now a reference.  
    TestClass& global = *(TestClass*)(void*)global_mem;
    
    void init_globals() {
      // this initializes a new TestClass object inside our memory buffer
      new (global_mem) TestClass("global");
    }
    
    int main(int argc, char **argv) {
      init_globals();
    

    这种方法的优点是您不需要更改任何其他代码,因为global 仍然只是称为global。不幸的是,维护init_globals 函数可能很麻烦。


    编辑:
    在后面的问题中发现,除了动态分配外,包含静态局部变量的函数在 Alchemy 初始化期间也无法调用。

    【讨论】:

    • +1 表示“它就像一串老式圣诞灯”,因为它就是这样。 :)
    猜你喜欢
    • 1970-01-01
    • 2016-10-02
    • 2016-09-27
    • 1970-01-01
    • 2021-03-15
    • 2014-10-12
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    相关资源
    最近更新 更多