【问题标题】:Use C++ managed Form from unmanaged C++ project使用非托管 C++ 项目中的 C++ 托管表单
【发布时间】:2014-12-10 07:16:18
【问题描述】:

我需要你的帮助,我搜索了很多关于这个问题的答案......

我有一个包含各种非托管 C++ 项目的解决方案,但现在我需要在主非托管项目中使用 Visual C++ 表单(即托管)并与之通信。 有可能做到吗?通过包装器,dll....怎么样?

我在 Google 上搜索了很多,但我发现的所有案例都在谈论如何将 Unmanaged 用于 Managed,或者是不完整的示例。我找到了这个例子,似乎它可以工作,但不能编译。

http://www.codeproject.com/Articles/9903/Calling-Managed-Code-from-Unmanaged-Code-and-vice

我正在使用 Visual Studio 2012。

非常感谢。

【问题讨论】:

  • 将 GUI 固定在不是为它设计的本机程序之上永远不会有好的结果。唯一的制胜策略是反其道而行之。让您的 EXE 成为托管程序,使用 C++/CLI 与现有代码进行互操作,重新构建为静态库或 DLL。
  • 我同意,但是不能让程序被管理,但是我找到了解决办法,我去贴一下
  • 你为什么投反对票?有更好的主意吗?

标签: c++ visual-c++ c++-cli unmanaged managed


【解决方案1】:

终于找到了解决办法……

1 - 当我想将 FORM 控件放入非托管代码(用于创建、显示、隐藏、设置控件值...)时,我将静态方法导出为 __declspec(dllexport)

2 - 当我想将信息从 FORM 发送到非托管代码时,我会使用回调。

我来解释一下……

首先...我创建一个 CLR 项目作为 DLL,创建一个带有一些控件的 windows Form (MyForm.h):

  • 1 个退出按钮
  • 1 个将信息发送到非托管代码的按钮
  • 和 1 个从非托管代码接收新状态的复选框

(我省略了visual studio生成的神)

namespace TestUnmanaged {
... code ommitted ...
    private: System::Void QuitBtn_Click(System::Object^  sender, System::EventArgs^  e) {
                 this->Close();
             }
    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
//Call to non managed function!!!!
                 CallToCallBack();
             }
    };
}

然后,我创建一个具有指向表单的指针的静态(非托管)类,并管理它的创建等。

//Type of my specific callback function
typedef std::function<bool (int& _msg)> T_CALLBACK_FUNC;

public class unmanagedClass
{
public: 

    unmanagedClass();
    ~unmanagedClass();

    void CreateForm( void );

    HWND getFormHandle(void) const;
    void setCallbackFunction(T_CALLBACK_FUNC _callbackFuntion);
    void callToCallbackFunction(int _value);
    //public for fast tests
    gcroot<TestUnmanaged::MyForm^> p;
private:
    HWND m_hWnd;
    T_CALLBACK_FUNC m_funcionCallback;
};

unmanagedClass s_unmanaged;

这是 .cpp 实现...

//////////////////////////////////////////////////////////////////////////
//          Static Functions for DLL_EXPORT
//////////////////////////////////////////////////////////////////////////

void CloseForm( void )
{   
    Application::Exit();
}

void CallToCallBack( void )
{
    int valor = 5;
    s_unmanaged.callToCallbackFunction(valor);
}


//////////////////////////////////////////////////////////////////////////
//          Methods for Unmanaged Class
//////////////////////////////////////////////////////////////////////////
HWND unmanagedClass::getFormHandle( void ) const
{
    return m_hWnd;
}

unmanagedClass::unmanagedClass()
{
    p = gcnew(TestUnmanaged::MyForm);
}

unmanagedClass::~unmanagedClass()
{
    delete (p);
}

void unmanagedClass::CreateForm( void )
{
    Application::Run(p);    
}

void unmanagedClass::setCallbackFunction( T_CALLBACK_FUNC _callbackFuntion )
{
    m_funcionCallback = _callbackFuntion;
}

void unmanagedClass::callToCallbackFunction( int _value )
{
    m_funcionCallback(_value);
}

现在,我创建了所有将导出为 dllexport 的静态函数:

__declspec(dllexport) void CreateFormDLL(void)
{
    s_unmanaged.CreateForm();
}

__declspec(dllexport) void CloseFormDLL(void)
{
    s_unmanaged.p->Close();
}

__declspec(dllexport) void ShowFormDLL(void)
{
    s_unmanaged.p->Show();  
}

__declspec(dllexport) void HideFormDLL(void)
{
    s_unmanaged.p->Hide();
}

__declspec (dllexport) void setCallbackFunctionDLL( T_CALLBACK_FUNC& _doFunction)
{
    s_unmanaged.setCallbackFunction(_doFunction);
}

__declspec (dllexport) void setCheckBoxDLL( bool _newValue )
{
    s_unmanaged.p->getCam01ChkBox()->Checked = _newValue;
}

__declspec (dllexport) HWND getFormHandleDLL( void )
{
    return (HWND)s_unmanaged.p->Handle.ToPointer();
}

现在....我创建 Win32 控制台应用程序项目并链接托管项目。这将是主进程和“ManagedWrapper”类。这里是源......

class ManagedWrapper
{
public:
    ManagedWrapper(void);
    ~ManagedWrapper(void);

    void init(void);

    void createForm(void);
    void showForm(void);
    void closeForm(void);
    void setCam01ChkBox(const bool _newValue);
private:
    void createFormThread(void);

    static bool callBackReceiver(int a);
};


#include "ManagedWrapper.h"
#include <thread>

__declspec(dllimport) void CreateFormDLL(void);
__declspec(dllimport) void CloseFormDLL(void);
__declspec(dllimport) void ShowFormDLL(void);
__declspec(dllimport) void HideFormDLL(void);
typedef std::function<bool (int& _msg)> T_CALLBACK_FUNC;
__declspec (dllimport) void setCallbackFunctionDLL( T_CALLBACK_FUNC& _doFunction);
__declspec (dllimport) void setCheckBoxDLL( bool _newValue );

ManagedWrapper::ManagedWrapper(void)
{
}

ManagedWrapper::~ManagedWrapper(void)
{
}

void ManagedWrapper::createForm( void )
{
    std::thread showThread (&ManagedWrapper::createFormThread, this);
    showThread.detach();
}

void ManagedWrapper::createFormThread( void )
{
    CreateFormDLL();
}

void ManagedWrapper::closeForm( void )
{
    CloseFormDLL();
}

void ManagedWrapper::showForm( void )
{
    ShowFormDLL();
}

void ManagedWrapper::init( void )
{
    setCallbackFunctionDLL(T_CALLBACK_FUNC(&ManagedWrapper::callBackReceiver));
}

bool ManagedWrapper::callBackReceiver( int a )
{
    printf("Hello world. Parameter value = %d\n",a);
    return true;
}

void ManagedWrapper::setCam01ChkBox( const bool _newValue )
{
    setCheckBoxDLL( _newValue );
}

最后....main() 中最简单的用法,创建表单,设置复选框值,如果用户单击按钮,回调函数将写入控制台...最后关闭。

int _tmain(int argc, _TCHAR* argv[])
{
    ManagedWrapper umWrap;
    umWrap.init();
    umWrap.createForm();
    system("PAUSE");
    umWrap.setCam01ChkBox(true);
    system("PAUSE");
    umWrap.setCam01ChkBox(false);
    system("PAUSE");
    umWrap.closeForm();
    return 0;
}

对不起,答案很长,但我相信这可能对某人有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 2011-01-01
    相关资源
    最近更新 更多