从非托管C ++项目使用C ++托管表单

时间:2014-10-15 09:11:50

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

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

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

我搜索了很多,但我发现的所有案例都谈到了如何使用Unmanaged to Managed,或者是不完整的例子。我找到了这个例子,似乎它有效,但是没有编译。

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

我正在使用Visual Studio 2012。

非常感谢。

1 个答案:

答案 0 :(得分:1)

最后我找到了解决方案......

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

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

我要解释一下......

首先......我创建一个CLR项目作为DLL,用一些控件创建一个Windows窗体(MyForm.h):

  • 1退出按钮
  • 发送信息至无管理代码的1个按钮
  • 和1从“无管理代码”
  • 接收新状态的复选框

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

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控制台App项目并链接了Managed项目。这将是主要的过程,并且是&#34; ManagedWrapper&#34;。这是源....

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()的最简单的用法,创建表单,设置复选框值,如果用户点击回调函数在控制台上写入的按钮......最后关闭。 / p>

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;
}

很抱歉答案很长,但我相信这对某些人可能有用。