Nebula3 in CLR

有用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会导致不能正解地进行初始化

解决方案(引用原文):

  1. WorkaroundSteps:
  2. Intheprojectproperties:
  3. 1.SetLinker\Advanced\EntryPointto""(emptystring)
  4. 2.SetLinker\System\SubsystemtoNotSet
  5. Step1:MakessurethattheCRTstartupcodeisinvoked.Thisisbecause,ifnoentrypointisspecified,thelinkerwillautomaticallyusemainCRTStartup,whichisdefinedintheCRTlibraries.mainCRTStartupwillmakesurethattheglobalobjectisinitializedcorrectly.
  6. Step2:Makessurethatthelinkerwilllookforthesymbol“main”.Thelinkerlooksfor“main”becausemainCRTStartupcallsmain()initsbody.ThedefaultoptionforaWinformsapplicationisSubsystem:WindowsandthismakesthelinkerlookforWinMain().
  7. Thanks
  8. SaritaBafna
  9. VisualC++team

测试程序:

  1. //N3CLR.cpp:mainprojectfile.
  2. #include"stdafx.h"
  3. #include"MainForm.h"
  4. #include"stdneb.h"
  5. #include"core/coreserver.h"
  6. #include"io/ioserver.h"
  7. usingnamespaceN3CLR;
  8. [STAThreadAttribute]
  9. intmain(array<System::String^>^args)
  10. {
  11. //EnablingWindowsXPvisualeffectsbeforeanycontrolsarecreated
  12. Application::EnableVisualStyles();
  13. Application::SetCompatibleTextRenderingDefault(false);
  14. Ptr<Core::CoreServer>coreServer=Core::CoreServer::Create();
  15. coreServer->Open();
  16. n_printf("HelloCLR!");
  17. coreServer->Close();
  18. coreServer=NULL;
  19. //Createthemainwindowandrunit
  20. Application::Run(gcnewMainForm());
  21. return0;
  22. }

Nebula3 in CLR_第1张图片

如果想嵌入到WinForm中的话, 需要更改DisplayDevice中的hWnd,我的做法是把DisplayDevice创建的窗口做为WinForm的子窗口.

注意InputDevice需要最顶层的窗口句柄来创建:

  1. //setthecooperativelevelofthedevice,we'refriendly
  2. //note:useWin32'sFindWindow()tofindourtoplevelwindowbecause
  3. //theDisplayDevicemayberunninginadifferentthread
  4. HWNDhWnd=FindWindow(NEBULA3_WINDOW_CLASS,NULL);
  5. if(0==hWnd)
  6. {
  7. hWnd=DisplayDevice::Instance()->GetParentWnd();
  8. }
  9. n_assert(0!=hWnd);

Nebula3 in CLR_第2张图片

你可能感兴趣的:(.net,Microsoft,Google,WinForm)