从 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”变量,然后一切正常。
有很多“类似”的问题,但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”变量,然后一切正常。