Bentley Communities
Bentley Communities
  • Site
  • User
  • Site
  • Search
  • User
  • Welcome
  • Products
  • Support
  • About
  • More
  • Cancel
MicroStation
  • Product Communities
  • More
MicroStation
MicroStation Wiki MDL - Native Code Application Development
    • Sign in

    • +MicroStation Wiki
    • +Administration Wiki
    • +Annotations Wiki
    • +Bentley View Wiki
    • +MicroStation PowerDraft
    • -Programming Wiki
      • A class to help create and modify text element
      • A Complete Example
      • A MicroStation VBA Example With Bentley ProjectWise
      • AddIn Development Using VB.NET
      • C# .NET Template with IPrimitiveCommandEvents Class
      • Capturing Graphics in Dynamic Views
      • Compiling MDL Applications
      • Database Manipulation
      • Debugging Native Code MDL Applications
      • Developing Code in VBA
      • Developing MicroStation Applications For DWG Files
      • Drag and Drop in MicroStation
      • Error: "Cannot save changes to VBA project 'Support' because it is read-only"
      • Getting And Setting Elements Using Graphic Groups In VBA [CS]
      • Getting Started with Visual Basic
      • How To Write A Recursive Routine In MicroStation VBA [CS]
      • Introducing Segment3D Methods In MicroStation V8 2004 Edition
      • Known issues in MDL and MicroStationAPI
      • Launching VBA Applications As Initapps Or Dgnapps [CS]
      • Learning MicroStation Addins Step by Step
      • MDL - Getting Started With XAttributes In MicroStation V8 XM Edition
      • MDL - Native Code Application Development
      • MDL Or MicroStation BASIC Choosing The Right Tool [TN]
      • MFC Dialog And Native Window Support
      • Microsoft Office VBA Patch Utility
      • MicroStation BASIC FAQ
      • MicroStation BASIC Limits [FAQ]
      • MicroStation Developer Documentation and Example Code
      • MicroStation Programming Advice
      • MicroStation SDK
      • MicroStation V8 Programming Tools Readme
      • MicroStation V8 VBA Programming Resources [CS]
      • MicroStation V8 XM Edition View Code Updates
      • MicroStation VBA Resources Revisited [CS]
      • Migrating Dimension Code To MicroStation V8
      • Migrating MDL Applications To Native Code
      • Mouse Wheel Events And The Visual Basic 6.0 IDE
      • Porting MDL Applications To MicroStation V8
      • Reading Elements From A Microsoft Access Database With VBA [CS]
      • Running MDL Applications
      • Scanning For MicroStation V8 Elements In VBA [CS]
      • Unleash A Workspace Wizard Automating Workspace Creation With MicroStation V8 And VBA [CS]
      • Using VBA To Detect The Current Or Last Used Command
      • Using VBA To Programmatically Export A VBA Project [CS]
      • Using VBA To Programmatically Import A VBA Projects Components And References [CS]
      • VBA -- Creating A Complex Application
      • VBA Interface Error: failed creating the comp manager - 0x80040583
      • VBA interface error: unable to get IDE
      • vba recording
      • Working With Levels In MicroStation VBA [CS]
      • Writing An MDL Application To Output Custom Placemarks To Google Earth
      • [V8i C++] PointCloud IPointCloudChannelDisplayHandler
    • +Visualization Wiki

     
     Questions about this article, topic, or product? Click here. 

    MDL - Native Code Application Development

    Publish Date: January 2006

    Bentley recommends using "native code" for application development with MicroStation V8 XM Edition -- native code being a term for an application written in Visual C/C++ and compiled into a DLL. In this article, three points will be addressed; how to build a new native code application; what needs to be done to convert existing applications to native code; and finally how to work with native code applications (i.e. load, debug, etc.) Before getting started, you need to make sure you have the right development tools. For native code application development in MicroStation V8 XM Edition, you need VisualStudio .NET 2003 Edition, which includes VisualC/C++ 7.1. It is also recommended to use C++ rules for compiling, since those provide a stricter environment to build applications with and can also help find programming errors. When you install the MicroStation SDK, the MicroStation Developer Shell will detect where VisualStudio is installed and run the vsvars32.bat file to set the correct paths and environment variables. Once the basic environment is established, the next thing to consider is actual development.

    For new applications, the development process is somewhat similar to traditional MDL application development. The main source code file name should be in the form FileName.cpp, where the the .cpp extension is associated to the Visual C/C++ compiler. Other important points include:

    • Native code applications need to have MdlMain as the entry point, since they still need to be loaded by the MDL loader in MicroStation
    • Use the macro DLLEXPORT for any function that needs to interact with external calls
    • All functions that are callbacks or otherwise called by MDL should include the syntax extern "C" so their names do not get mangled in the compilation process
    • All memory allocations should use the dlmSystem... family of functions to allow interaction with MDL and memory management for the application resources by MicroStation
    • For access to MicroStation's global data structures, include msvar.fdf or dloadlib.h
    • To integrate Command entry points into the application, declare MdlCommandNumber and MdlCommandName arrays in MdlMain and then use the mdlSystem_RegisterCommandNumbers and mdlSystem_RegisterCommandNames functions to publish the functions to MicroStation


    Private MdlCommandName commandName[] =
    {
    {AddData, "AddData"},
    {ReviewData, "ReviewData"},
    0
    };

    Private MdlCommandNumber commandNumber[] =
        {
            {templateapp_command_test,                     CMD_TEMPLATEAPP_TEST },
            {templateapp_command_sctest,                   CMD_TEMPLATEAPP_SCTEST },
            0
        };

    /* **//**
    * @description Main entry point for the example.
    * @param argc IN Number of arguments passed in argv
    * @param *argv[] IN Array of pointers to arguments
    * @return SUCCESS
    * @remarks
    + + + ~-+ + + */
    extern "C"  DLLEXPORT int   MdlMain
    (
    int             argc,
    char           *argv[]
    )
        {
        RscFileHandle   rscFileH;   /* a resource file handle */

        mdlResource_openFile (&rscFileH, NULL, 0);
        mdlSystem_registerCommandNumbers (commandNumber);
        mdlParse_loadCommandTable (NULL);

        mdlSystem_setFunction (SYSTEM_UNLOAD_PROGRAM, templateapp_onUnload);

        mdlState_registerStringIds (STRINGLISTID_CommandNames,  STRINGLISTID_CommandNames);

        return SUCCESS;
        }


    To use MicroStation resource-based dialogs and other MDL resource types in native code applications, no special code handling is necessary. However, since traditional MicroStation applications are a combination of code and resources, you need to build at least one MDL resource of type DLLMDLAPP to allow MicroStation to load the native code application as a MicroStation application. This resource type contains the DLL and MDL application names. This allows MicroStation's MDL loader to call the DLL's entry point. The definition looks like this:


    #define DLLAPPID 1
    /* associate app with dll */
    DllMdlApp DLLAPPID =
    {
    "PlaceLineToolDLL", "PlaceLineToolMDL"
    }

    This is typically included in a resource source file that is used to build a resource file, which is then merged into the resulting MA file.

    To compile or build the native code application, it is still recommended to create and use a MAKE file and the MicroStation Developer Shell delivered with the MicroStation SDK to set the environment accordingly for both MDL and VisualStudio. More information on MAKE files can be found in the MDL Programmer Guide. The MAKE file needs to include rules for building a DLL. These rules are defined by setting a series of macros that are specific to an application as well as including general rules that are defined in dlmcomp.mki and dlmlink.mki.


    #------------------------------------------------
    # Set up to use dlrncornp.rnki and dlrnlink.rnki
    #------------------------------------------------
    dlrnObjs = $(0) $(appNarne) $(oext)
    DLM_DEST = $(rndlapps)
    DLM_OBJECT_DEST = $(0)
    DLM_LIBDEF_SRC = $(baseDir)
    DLM_NAME = $(appNarne)
    DLM_ENTRY_NAME = dllentry
    DLM_RESL_NAME = fileresl
    DLM_OBJECT_FILES = $(dlrnObjs)
    DLM_NO_DLS = 1 # Used DLLEXPORT in .c file
    DLM_NO_DEF = 1
    DLM_NOENTRY = 1
    DLM_NO_SIGN = 1
    DLM_LIBRARY_FILES = $(mdlLibs)dgnfileio.lib
    $ (mdlLibs) tool subs. lib $(mdlLibs)ditemlib.lib
    #------------------------------------------------
    # Compile the source files for the DLM
    #------------------------------------------------
    %include dlmcomp.mki


    The relationships in the make file need to be added to build the object file from the source file. This is done with the following syntax:


    $(o)$(appName)$(oext): $(baseDir)$(appName) .cpp \
    $(privateInc)$(appName).h \
    $ (genSrc) $ (appName)cmd.h


    The target output file are identified to the left of the colon and the dependent input files are identified to the right. The final output of the build process will be two files: The first a DLL and the second an MA file that contains the resources for the application.


    #-----------------------------------------------------------------------
    # Merge Objects into one file
    # ~--------------
    $(mdIApps)$(appName).ma : $(appRscs)
    $(msg)
    >$(0)make.opt
    -o$@
    $(appRscs)
    <
    $(RLibCmd) @$(o)make.opt
    ~time


    Another important detail that application developers need to be aware of is memory allocation routines. If memory is shared between native code and MDL code, then it is very important to use dlmSystem_... wrappers for the standard functions. By using dlmSystem_... functions, memory allocations are associated with the application, so when the application is unloaded the allocated memory can be cleaned up properly. Also, memory can be shared safely with MDL code.

    Migrating existing applications to native code requires some minor modification to source code. Before starting this process, it is recommended that you clean out the existing application and its intermediate files. This can be done using the bmake -aD command or by simply deleting the MA file and all the files in ..\mdl\objects\, ..\mdl\rscObjects\, ..\mdl\reqObjects\, and other similar locations. You can also force the bmake process to build MC to OBJ files and then use the VisualStudio compiler. Next, you need to add the DLLMDLAPP resource to the application. Since a command table resource is in most applications, the most logical place to add this resource definition is usually in the file that contains the command table definition. This allows the DLLMDLAPP resource addition without modification to the MKE file. Next, add the MdlMain definition to the source code. This is necessary to provide an entry point to the application. In MdlMain, the application needs to have the MdlCommandNumber and/or MdlCommandName arrays and the corresponding calls to mdlSystem_registerCommandName and/or mdlSystem_RegisterCommandNumber functions. The next step is to change the memory allocation routines to use the dlmSystem_... functions to integrate with MicroStation's memory allocation. There may be some other minor housekeeping chores necessary, since things like NULL in native code do not equate to 0 as they do in MDL.

    Once the application is built, the next task to consider is debugging. To debug native code applications, you need to attach to the ustation.exe process to the debugger. There are a several ways to do this. One is to start MicroStation in the debugger by using the following command line from the MicroStation Development Shell:

    msdev %ms%\ustation.exe

    This starts the Developer Studio IDE with MicroStation loaded. You can then set the debug breaks at the functions in your application. The alternate method is to start MicroStation and then start your debugger, in this example Developer Studio (msdev). Then inside Developer Studio attach to the ustation.exe process from the Build > Start Debug > Attach to Process menu item.

    From this list, select the ustation.exe process and then add your DLL as an additional DLL to debug. From the Project > Settings menu, select the first tab then in the combo box, select additional DLLs. Then in the main section, select the DLL to debug.

    Once MicroStation is running in the debug environment, you can set break points on your functions. One tip is to use the first method of starting MicroStation under the debugger and then setting a break point at MdlMain to catch your application at load time. For a more brute force method or when an InitApps is involved, you can use the following code line in your application:

    __asm int 3;

    This will cause the application to halt at this instruction, but it can only be used when the application is being actively debugged.

    There are numerous reasons why MDL developers should focus on developing native code applications -- the C++ compiler and debugging environment are just two of the benefits. More documentation, articles, and examples will be provided in the future regarding this topic.

    • MDL
    • BDNzine
    • Share
    • History
    • More
    • Cancel
    • Dan Koval Created by Bentley Colleague Dan Koval
    • When: Thu, Sep 5 2013 4:22 PM
    • Revisions: 1
    • Comments: 0
    Recommended
    Related
    Communities
    • Home
    • Getting Started
    • Community Central
    • Products
    • Support
    • Secure File Upload
    • Feedback
    Support and Services
    • Home
    • Product Support
    • Downloads
    • Subscription Services Portal
    Training and Learning
    • Home
    • About Bentley Institute
    • My Learning History
    • Reference Books
    Social Media
    •    LinkedIn
    •    Facebook
    •    Twitter
    •    YouTube
    •    RSS Feed
    •    Email

    © 2021 Bentley Systems, Incorporated  |  Contact Us  |  Privacy |  Terms of Use  |  Cookies