一步步学习MDL-CE[1]
[0] [2] [3] [4] [5] [6] [7] [8]
第一章、建立一个最简单的MDL应用程序
本章将带领您从零开始一步步建立一个最简单的Hello World本机代码MDL应用程序,该程序能够在Mstn中装载运行。
1、在任一驱动器上建立文件夹\MDLSource\HelloWorld,我是在D:上建立的;
2、启动一个文本编辑器(当然可以启动VS2015用作编辑器),在其中键入如下内容并保存为文件D:\MDLSource\HelloWorld\HelloWorld.cpp。该文件中含有程序的入口点函数MdlMain,当应用程序被装载后会从该入口点开始执行。我们在该函数中调用了MDL C API函数mdlDialog_dmsgsPrint用以弹出一个消息框显示Hello World字样。
/*-------------------------------------------------------------+ | HelloWorld.cpp | +-------------------------------------------------------------*/ #include <Mstn\MdlApi\MdlApi.h> extern "C" DLLEXPORT void MdlMain (int argc, WCharCP argv[]) { mdlDialog_dmsgsPrint (L"Hello World"); }
对以上代码的几点解释如下:
- CE版的头文件被细分到了许多个文件夹中,所以,在包含头文件时需要用到多级路径,如上面的Mstn\MdlApi;
- 这个MdlApi.h头文件很重要,包含了它后大部分类和函数功能都被引入了;
- 一个MDL程序的入口函数必须叫做MdlMain,其参数为int和WCharCP。注意,CE版的MdlMain的第二个参数由V8i的char*变成了WCharCP(即WChar const *),这也是CE SDK与V8i SDK的一个重要区别就是:所有涉及到文字的部分都要改用Unicode;
- extern "C"使MdlMain函数以C语言的形式而非C++的形式生成到obj文件中,这样保证没有函数重载的发生;
- DLLEXPORT被定义为__declspec(dllexport),表明MdlMain函数需要被导出。
3、在文本编辑器中键入如下内容并保存为文件D:\MDLSource\HelloWorld\HelloWorld.r。该文件中定义了DllMdlApp资源,该资源的作用是将MA(实际上不是MA文件名而是任务标识符)与指定的DLL文件关联起来。
#include <Mstn\MdlApi\rscdefs.r.h> #define DLLAPPID 1 DllMdlApp DLLAPPID = { L"HELLOWORLD", L"HelloWorld" // taskid, dllName }
对以上代码的几点解释如下:
- DllMdlApp是被定义在rscdef.r.h文件中的一个结构体。它由两部分组成:任务标识(TaskId)和DLL名称;
- TaskId基本上可以理解为ma文件的名称,但不完全对应。TaskId会被自动转换为全部大写字符而且有长度的限制,只有在你的ma文件的名字非常长的情况下,TaskId才会发生不与文件名相同的情况;
- MDL程序由一个ma和一个dll两个文件组成,装载时先找到ma,再通过这个DllMdlApp结构找到对应的dll文件来装载。一般情况下我们都会将ma和dll的名称保持一致,当然也可以不一致。
4、将如下内容复制并粘贴成一个叫做HelloWorld.mke的文件保存到D:\MDLSource\HelloWorld下。该文件是生成项目的控制文件。在项目生成过程中,bmake读取该文件的内容然后调用相应的编译器和链接器从源文件生成最终的MA和DLL。
#-------------------------------------------------------------------------------------- # MstnCE HelloWorld.mke #-------------------------------------------------------------------------------------- PolicyFile = MicroStationPolicy.mki DEFAULT_TARGET_PROCESSOR_ARCHITECTURE=x64 appName = HelloWorld appObjs = $(o)$(appName)$(oext) appRscs = $(o)$(appName).rsc baseDir = $(_MakeFilePath) mdlLibs = $(MSMDE)library/ %include mdl.mki #---------------------------------------------------------------------- # Create needed output directories if they don't exist #---------------------------------------------------------------------- always: ~mkdir $(o) ~mkdir $(rscObjects) ~mkdir $(reqdObjs) #---------------------------------------------------------------------- # Define macros for files included in our link and resource merge #---------------------------------------------------------------------- DLM_NO_SIGN = 1 DLM_OBJECT_DEST = $(o) DLM_NAME = $(appName) DLM_OBJECT_FILES = $(appObjs) DLM_NO_DLS = 1 DLM_NO_DEF = 1 DLM_NOENTRY = 1 DLM_NO_MANIFEST = 1 DLM_DEST = $(mdlapps) LINKER_LIBRARIES = $(mdlLibs)bentley.lib \ $(mdlLibs)mdlbltin.lib \ $(mdlLibs)BentleyGeom.lib \ $(mdlLibs)DgnPlatform.lib #-------------------------------------------- # Create command table and header file #-------------------------------------------- #$(baseDir)$(appName)cmd.h : $(baseDir)$(appName)cmd.r #$(o)$(appName)cmd.rsc : $(baseDir)$(appName)cmd.r #----------------------------------------------------------------------- # Generate resource files #----------------------------------------------------------------------- $(o)$(appName).rsc : $(baseDir)$(appName).r #---------------------------------------------------------------------- # Generate MA #---------------------------------------------------------------------- $(mdlapps)$(appName).ma : $(appRscs) $(msg) > $(o)make.opt -o$@ $(appRscs) < $(RLibCmd) @$(o)make.opt ~time #----------------------------------------------------------------------------------------- # Builds any necessary CODE modules and link them to DLL #----------------------------------------------------------------------------------------- $(o)$(appName)$(oext) : $(baseDir)$(appName).cpp %include dlmlink.mki
这个mke文件控制了整个项目的生成过程,其内容相对复杂,详细介绍请见下一章。
5、右击“开始 > 所有程序 > Bentley > MicroStation CONNECT Edition SDK > MicroStation CONNECT Edition SDK”,在弹出的菜单中选择“以管理员运行”启动MDL程序开发环境。在开发环境命令提示符后键入cd /d d:\mdlsource\helloworld并回车进入我们的项目所在目录,然后再键入bmake –a来生成HelloWorld.ma和HelloWorld.dll。这些生成的文件位于…\MicroStation\mdlapps目录下。
对于以上两个键入命令做如下解释:
- cd命令是change directory(改变目录)的缩写,用它可以进入到任意文件下;
- /d参数表示可改变驱动器(driver,即盘符的意思)。由于我们要从C:盘改到D:盘,或使用/d参数。您也可以先键入d:来改换到D:盘;
- bmake不是Windows的命令,而是我们MicroStation SDK带有的命令,请看C:\Program Files\Bentley\MicroStationCONNECTSDK\bin下就有exe这个执行文件(Windows中的文件或文件夹是不区分大小写的)。该命令的作用就是按照mke文件中的指令来生成项目(即从源代码生成可执行的ma和dll文件),相当于VS中的Build Solution(生成解决方案)菜单项;
- -a参数表示all的意思,即:无论您是否修改过源代码,都重新生成所有目标文件。相当于VS中的Rebuild Solution(重生成解决方案);
【技巧】:可按照SDK Readme中Developer Notes部分的步骤将菜单MicroStation CONNECT Edition SDK发送成Windows桌面的一个快捷方式,然后右击该快捷方式选属性打开快捷方式属性对话框,然后在Shortcut页点击Advanced按钮打开高级属性设置对话框,勾选Run as administrator并一路按Ok按钮确定。今后就可以方便地直接点击桌面的这个快捷方式启动开发环境了。
6、启动MicroStation CE,任意打开一个DGN文件。保证当前Ribbon界面中的工作流是Drawing或Modeling(我目前使用的是英文版的MicroStation CE),然后选择Utilities页下的MDL Applications打开MDL对话框,在该对话框下部的Available Applications列表框中找到并选中HELLOWORLD,然后点按钮Load按钮装载我们的MDL应用程序。此时会看到一个写有Hello World字样的消息框弹出。如下图所示:
7、在您想要重新生成您的HelloWorld项目前需要首先卸载该应用,否则将会遇到如下图所示的错误提示。卸载方法是在以上MDL对话框上部的Loaded Applications中选中HELLOWORLD,然后点击Unload按钮即可。
【技巧】:还可以通过键入命令来实现MDL应用程序的装载和卸载。如下图所示打开键入命令对话框,输入MDL LOAD HelloWorld来装载应用,输入MDL UNLOAD HelloWorld来卸载应用。
【注意】:Mstn SDK开发环境严重依赖Windows的短路径(即8.3格式)。如果您安装VS或Mstn的盘不支持短路径,请参考如下英文文章用FSUTIL.EXE进行设置。如果还是无法设置成功,则最好将VS和Mstn安装到一个支持短路径的盘上去。
Windows Server 2012 File Server Tip: Disable 8.3 Naming (and strip those short names too)