从本机应用程序调用托管代码时,CLR何时以及如何初始化?

时间:2018-10-01 19:00:33

标签: c# c++ c++-cli interop managed

我正在运行一个简短的实验,以查看从本机C ++(MFC)应用程序显示一些WPF窗口会有多困难。在看到this和后来的this之后,我决定在.NET类库.DLL周围使用C ++ / CLI包装DLL。

[native C++ .exe] -> [C++/CLI wrapper .lib] -> [C# Class Library .dll]

可以认为,这将使我的本机C ++应用程序保持不受管理,并且不需要使用/ clr编译选项。

在跳过显示窗口并启动调度程序所需的一些障碍之后,我随后使沙盒代码正常工作。一个本机控制台应用程序启动,显示一个WPF窗口,允许用户输入数字,并在关闭窗口时返回该数字并将其写入控制台输出。

现在,我过去使用CLI进行反向操作(从托管调用非托管代码),但是朝这个方向前进让我有些困惑。

在阅读了有关如何为.NET可执行文件初始化CLR的一些资料之后,例如在this SO answer's comments中讨论了CLR“进程”以及如何将Execution Engine引导启动的讨论,我想知道在不对主要可执行文件进行管理或与.NET相关联的情况下,何时以及如何发生所有这些事情?另外,CLR组件的“生命周期”是什么-如果我进行单个方法调用,垃圾收集器和JIT编译器是否会初始化和销毁​​?他们是否接受我的流程直到退出?这会以任何方式影响我的本机应用程序吗?

我的测试项目的代码如下所示,并且据我所知可以正常工作。


ConsoleApplication(.exe)

将CLIWrapper.lib添加到“ AdditionalDependencies”中

mainfile.cpp

#include "CLIInterface.h"

int main()
{
    APIWrapper wrapper;
    int rint = wrapper.GetAnInteger();

    char buffer[100];
    snprintf(buffer, sizeof(buffer), "Value: %d\n", rint);
    std::cout << buffer;
}

CLIInterface.h

class APIWrapperPrivate;

class APIWrapper
{
private:
    APIWrapperPrivate* _private;
public:
    APIWrapper();
    ~APIWrapper();
    int GetAnInteger();
};

CLIWrapper(.dll)

CLIWrapper.cpp

#include <msclr\auto_gcroot.h>
#using "..\CSharpLibrary\bin\Debug\CSharpLibrary.dll"

using namespace System;
using namespace System::Runtime::InteropServices;

class APIWrapperPrivate
{
public:
    msclr::auto_gcroot<CSharpLibrary::TheCSharpInterface^> theCSharpInterface;
};

class __declspec(dllexport) APIWrapper
{
private:
    APIWrapperPrivate* _private;

public:
    APIWrapper()
    {
        _private = new APIWrapperPrivate();
        _private->theCSharpInterface = gcnew CSharpLibrary ::TheCSharpInterface();
    }

    ~APIWrapper()
    {
        delete _private;
    }

    int GetAnInteger()
    {
        return _private->theCSharpInterface->GetAnItegerValue();
    }
};

CSharpLibrary(.dll)

TheCSharpInterface.cs

public class TheCSharpInterface
{
    public int GetAnItegerValue()
    {
        int anIntegerValue;

        ThreadStart ThreadProc = new ThreadStart(() =>
        {
            SynchronizationContext.SetSynchronizationContext(
               new DispatcherSynchronizationContext(
                   Dispatcher.CurrentDispatcher));

            SomeWindow window = new SomeWindow();
            window.Closed += (sender, e) =>
            {
                anIntegerValue = window.Power;
                Dispatcher.CurrentDispatcher.InvokeShutdown();
            };
            window.Show();
            Dispatcher.Run();
        });

        Thread t = new Thread(ThreadProc);
        t.SetApartmentState(ApartmentState.STA);
        t.IsBackground = true;
        t.Start();
        t.Join();

        return this.anIntegerValue;
    }
}

SomeWindow.xaml

带有整数滑块控件的wpf窗口

0 个答案:

没有答案