有用N3 + CLR做界面的冲动
新建一个CLR WinForm工程, 直接引入N3的头文件和库进行编译........
编译不过, 找了半天才发现原因
晕死, .Net和N3都有个System命名空间, 没法改Microsoft的东西, 只好把N3的System改成了NSystem
然后就是链接不过
一是__fastcall不被CLR支持, 改成__cdecl (/Gd)重遍
二是Multi-threaded Debug (/MTd)跟/clr冲突, 改成Multi-threaded Debug DLL (/MDd)
终于链接过了.............
启动程序, Crash掉
拿着关键字就去问google, 没想到MSDN论坛上还真有解决方法(感谢我的先驱们, 我成功是了站在你们的"尸体"上)
原因是N3的对象系统在ImplementClass时定义了一些静态对象, 如果直接用CLR会导致不能正解地进行初始化
解决方案(引用原文):
- WorkaroundSteps:
- Intheprojectproperties:
- 1.SetLinker/Advanced/EntryPointto""(emptystring)
- 2.SetLinker/System/SubsystemtoNotSet
- Step1:MakessurethattheCRTstartupcodeisinvoked.Thisisbecause,ifnoentrypointisspecified,thelinkerwillautomaticallyusemainCRTStartup,whichisdefinedintheCRTlibraries.mainCRTStartupwillmakesurethattheglobalobjectisinitializedcorrectly.
- Step2:Makessurethatthelinkerwilllookforthesymbol“main”.Thelinkerlooksfor“main”becausemainCRTStartupcallsmain()initsbody.ThedefaultoptionforaWinformsapplicationisSubsystem:WindowsandthismakesthelinkerlookforWinMain().
- Thanks
- SaritaBafna
- VisualC++team
测试程序:
- //N3CLR.cpp:mainprojectfile.
- #include"stdafx.h"
- #include"MainForm.h"
- #include"stdneb.h"
- #include"core/coreserver.h"
- #include"io/ioserver.h"
- usingnamespaceN3CLR;
- [STAThreadAttribute]
- intmain(array<System::String^>^args)
- {
- //EnablingWindowsXPvisualeffectsbeforeanycontrolsarecreated
- Application::EnableVisualStyles();
- Application::SetCompatibleTextRenderingDefault(false);
- Ptr<Core::CoreServer>coreServer=Core::CoreServer::Create();
- coreServer->Open();
- n_printf("HelloCLR!");
- coreServer->Close();
- coreServer=NULL;
- //Createthemainwindowandrunit
- Application::Run(gcnewMainForm());
- return0;
- }
如果想嵌入到WinForm中的话, 需要更改DisplayDevice中的hWnd,我的做法是把DisplayDevice创建的窗口做为WinForm的子窗口.
注意InputDevice需要最顶层的窗口句柄来创建:
- //setthecooperativelevelofthedevice,we'refriendly
- //note:useWin32'sFindWindow()tofindourtoplevelwindowbecause
- //theDisplayDevicemayberunninginadifferentthread
- HWNDhWnd=FindWindow(NEBULA3_WINDOW_CLASS,NULL);
- if(0==hWnd)
- {
- hWnd=DisplayDevice::Instance()->GetParentWnd();
- }
- n_assert(0!=hWnd);