在类中使用函数指针会使编译器崩溃(但在函数内部工作)

时间:2016-07-08 04:01:28

标签: class visual-c++ c++-cli

参考类

class commandsListClass
{
public:
    std::string name;
    std::string description;
    std::vector<std::string> commands;
    columnHeaders headersRequired;
    void (*function)(System::Object ^ );
    std::string recoveryFileHeader;
    void reset()
    {
        name = "";
        description = "";
        commands.clear();
        headersRequired.reset();
        recoveryFileHeader = "";
        function = dummyFunc; // dummyFunc uses the same members as the intended - this is to ensure it is defined. DummyFunc is empty, returns void etc
    }
    commandsListClass()
    {
        reset();
    }
};

目前,如果我运行以下代码,编译器崩溃

// This crashes the compiler
System::Threading::ThreadPool::QueueUserWorkItem(gcnew System::Threading::WaitCallback(global::commandsList[index].function ), ti);

Visual of the crashed compiler

1>------ Build started: Project: MyProject, Configuration: Release x64 ------
1>  project.cpp
1>c:\users\guy\documents\visual studio 2012\projects\MyProject\MyProject\Form1.h(807): fatal error C1001: An internal error has occurred in the compiler.
1>  (compiler file 'msc1.cpp', line 1443)
1>   To work around this problem, try simplifying or changing the program near the locations listed above.
1>  Please choose the Technical Support command on the Visual C++ 
1>   Help menu, or open the Technical Support help file for more information
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

如果我在调用函数内部声明一个成员,并将其设置为global :: commandsList [index] .function,则编译并正确运行

// This runs correctly    
void (*func)(System::Object ^);
func = global::commandsList[index].function;
System::Threading::ThreadPool::QueueUserWorkItem(gcnew System::Threading::WaitCallback(func ), ti);

global :: commandsList是一个类型为commandsListClass

的向量

有什么想法吗?浏览Google和SO建议将编译器更改为不优化,我试过没有成功。代码的编写方式如下:

  • 如果index未指向global :: commandsList vector的有效成员,则无法访问代码中的那一点
  • 保证函数变量可以设置为创建时的dummyFunc,也可以设置为代码中其他位置设置的正确(请求)函数。

非常感谢任何帮助。

编辑1:这是使用Visual Studio 2012,Windows 7 x64

1 个答案:

答案 0 :(得分:0)

这是一个简化的回购:

public delegate void MyDel(Object^);

void g(Object^) {}

struct A {
    static void(*fs)(Object^);
    void(*f)(Object^);
    gcroot<MyDel^> del;
};

void(*fg)(Object^);

void h()
{
    void (*f)(Object^);
    A a;

    gcnew MyDel(f);
    gcnew MyDel(fg);
    gcnew MyDel(a.fs);
    a.del = gcnew MyDel(g);

    //gcnew MyDel(a.f);  // this line fails

    // work around
    f = a.f;
    gcnew MyDel(f);
}

只有非静态成员变量失败。看起来像编译器错误。使用本地中间人解决它。

或者更好的是卢卡斯建议使用gcroot。