终于找到了解决办法……
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;
}
对不起,答案很长,但我相信这可能对某人有用。