从 C++/CLI 创建 .dll MFC 对话框 - 加载程序锁定

Creating .dll MFC Dialog from C++/CLI - Loader lock

有很多“类似”的问题,但none完全像这样。

我的任务是通过 dotnet 将现有的 MFC C++ 应用程序与 AutoCAD 连接 api。

所以我为 AutoCAD 创建了 C#,C++/CLI 作为中间人,又创建了一个 C++ 来实现抽象 class,然后是 MFC C++。 每个项目都编译为 .dll。 MFC C++ 有这个 class 和一个负责创建对话框的函数 window.

//thirdParty.h
#pragma once
#ifdef THIRDPARTY_EXPORTS
#define THIRDPARTY_API __declspec(dllexport)
#else
#define THIRDPARTY_API __declspec(dllimport)
#endif

class THIRDPARTY_API ThirdPartyIO
{
public:
    void OpenDialog();
};

//thirdParty.cpp
void ThirdParty::ThirdPartyIO::OpenDialog()
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    GUI::DlgMain dlg;
    dlg.DoModal();
}

然后我有我的 C++,抽象 class 将在其中实现,但现在我用它来创建 ThirdPartyIO

的实例
//PluginTester.h
#pragma once
#include "thirdPartyIO.h"

#ifdef PLUGINTESTER_EXPORTS
#define PLUGINTESTER_API __declspec(dllexport)
#else
#define PLUGINTESTER_API __declspec(dllimport)
#endif

class PLUGINTESTER_API Tester
{
public:
    ThirdParty::ThirdPartyIO io;
    void Call();
};

#include "PluginTester.h"

void Tester::Call()
{   
    io.OpenDialog();
}

然后是C++/CLI调解器class

//Mediator.h
#pragma once

#include "Tester.h"
#include "vcclr.h"


namespace Wrapper
{
    public ref class Mediator
    {
    public:
        Mediator();
        ~Mediator();
        !Mediator();
        void Call();

    private:
        void Destroy();
        Tester *m_pInterface = nullptr;
    };
}

//Mediator.cpp
#include "Mediator.h"
#include <string>
#include <Windows.h>


Wrapper::Mediator::Mediator() : m_pInterface(new Tester)
{

}

Wrapper::Mediator::~Mediator()
{
    Destroy();
}

Wrapper::Mediator::!Mediator()
{
    Destroy();
}

void Wrapper::Mediator::Destroy()
{
    if (m_pInterface != nullptr)
    {
        delete m_pInterface;
        m_pInterface = nullptr;
    }
}

void Wrapper::Mediator::Call()
{
    return m_pInterface->Call();
}

最后是我的 C# 插件 class

using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.ApplicationServices;
using Wrapper;


namespace ACADPlugin
{
    public class ACADPlugin : IExtensionApplication
    {
        private Mediator m_wrapper;

        [CommandMethod("InstancePlugin", CommandFlags.Modal)]
        public void CreateInstance()
        {
            m_wrapper = new Mediator();
           // m_wrapper.Call();
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            ed.WriteMessage("\nFirstCommand called");
        }

        void IExtensionApplication.Initialize()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            ed.WriteMessage("\nPlugin successfully loaded!");
        }

        void IExtensionApplication.Terminate()
        {

        }
    }
}

现在的问题是,即使我不调用“调用”方法,如果我在 thirdParty.cpp 某处使用 AFX_MANAGE_STATE,我也会得到 OS 加载程序锁定异常。我知道它可以关闭,但这不是重点。似乎 AFX_MANAGE_STATE 正在调用托管代码或其他东西,但我真的不明白为什么或如何,因为它是 C++ 宏。

如果我不使用 AFX_MANAGE_STATE,我不会得到锁定异常,但我无法创建对话框,因为我得到 mfc140ud.dll 错误。

如果我关闭异常,它有时会工作,但它似乎很慢,如果我什至创建对话框 window,ACAD 将变得无法使用,它并非完全没有响应,但它会注册每 2 秒左右发生一次。

如果有人有任何想法,我将不胜感激。

谢谢。

据我所知,这是由于在堆栈上的 mfc .cpp 文件中创建“theApp”造成的。所以对话框显示,甚至不是我调用 DoModal 的那个,而是在 InitInstance 方法中创建的那个。

解决方案是注释掉“theApp”变量,然后一切正常。