通过 CLI 包装器在非托管 C++ 中使用 C#.NET Winform - 需要线程?

Posted

技术标签:

【中文标题】通过 CLI 包装器在非托管 C++ 中使用 C#.NET Winform - 需要线程?【英文标题】:C#.NET Winform in unmanaged C++ via CLI wrapper - thread required? 【发布时间】:2014-10-03 09:55:20 【问题描述】:

我正在尝试制作一个程序,通过 C++/CLI 包装类从非托管 C++ 调用 C#.NET 表单。

表单按预期显示,但启动表单后的任何代码都不会执行。我不太了解线程,但我觉得这可能是我的问题。

这是我的 main.cpp:

int main()

    int  fred;
    TestFormWrapper testForm;   

    testForm.ShowForm();

    std::cin >> fred;  // to allow me to see the form before and after label change

    testForm.ChangeLabel(); 

    std::cin >> fred;  // to allow me to see the form before and after label change

    return 0;


这是我的 CLI 包装器:

class __declspec(dllexport) TestFormWrapper

private:
    TestFormWrapperPrivate* _private;

public:
    TestFormWrapper()
    
        _private = new TestFormWrapperPrivate();
        _private->testForm = gcnew ManagedForms::TestForm();

    

    ~TestFormWrapper()
    
        delete _private;
    


    void ShowForm()
    
        System::Windows::Forms::Application::Run(_private->testForm);
    

    void ChangeLabel()
    
        _private->testForm->changeLabel();
        _private->testForm->Refresh();
       

;

我的控制台(我在其中输入数字以推进执行)在我关闭表单之前不允许任何输入。我在这里的实际目标是在其他代码执行时更新表单,例如显示来自主程序线程的数据。

有什么想法吗?

【问题讨论】:

你倒置了线程 - UI 总是在前台线程(通常被认为是主线程)上运行,其他工作发生在后台线程上。 @PanagiotisKanavos 谢谢。我对线程非常不熟悉,有没有简单的解决方法? UI 线程是 UI 线程,因为它运行消息循环。该循环是Application::Run。进程主线程成为UI线程还是工作线程都没有关系。 【参考方案1】:

现在你根本没有任何多线程。

C++ 处理线程在其调用的 C# 函数返回之前无法继续。这样 C# 函数应该启动一个新线程并快速返回。

然后新线程可以激活消息循环 (Application::Run) 并显示 UI。

您将需要使用 Control::Invoke() 从其他线程访问 UI。希望是代码的 C# 部分执行此操作 - 匿名 lambdas 等以比 C++ 所需的代码少得多的代码完成。

【讨论】:

以上是关于通过 CLI 包装器在非托管 C++ 中使用 C#.NET Winform - 需要线程?的主要内容,如果未能解决你的问题,请参考以下文章

C# 使用 CLI 包装器调用非托管 C++

用 C++/CLI 包装非托管 C++ - 一种正确的方法

使用 C++/CLI 包装器将二维数组从 C# 传递到非托管 C++

从非托管 c++ 调用 C# 函数(通过托管包装器)

尝试从 C++/CLI 调用非托管 C++ 时解决错误

从 c# 访问 C++ .lib 库