【问题标题】:Creating .dll MFC Dialog from C++/CLI - Loader lock从 C++/CLI 创建 .dll MFC 对话框 - 加载程序锁定
【发布时间】:2020-10-16 03:40:08
【问题描述】:

有很多“相似”的问题,但没有一个完全像这样。

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

所以我为 AutoCAD 创建了 C#,C++/CLI 作为中间人,又一个 C++ 用于实现抽象类,然后是 MFC C++。 每个项目都编译为 .dll。 MFC C++ 有这个类,其中一个函数负责创建对话窗口。

//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++ 将在其中实现抽象类,但现在我使用它来创建 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 中介类

//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# 类

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 Loader 锁定异常。我知道它可以关闭,但这不是重点。似乎 AFX_MANAGE_STATE 正在调用托管代码或其他东西,但我真的不明白为什么或如何,因为它是 C++ 宏。

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

如果我关闭异常,它有时会起作用,但它似乎很慢,如果我什至创建对话窗口,ACAD 就无法使用,它并非完全没有响应,但它每 2 秒左右注册一次事件.

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

谢谢。

【问题讨论】:

    标签: c++ .net mfc clr


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 2015-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多