Help with moving MDL application to Ustn Connect - LinkageHeader structure not being found

Hello Everyone,

I am having trouble compiling the MT file to the R file. Below is the message from the BMAKE

The line number 40 in the .H file is "LinkageHeader lnkHdr"

[== Building C:\...\<appname>Linktyp.r, (C:\...\<appname>Linktyp.mt) ==]
rsctype @C:\...\AppData\Local\Temp\Bentley\MicroStationSDK\objects\make.opt
MicroStation Type Resource File Generator 03.17.02
C:\...\<appname>Attr.h(40) : error: bad struct/union definition: expected type
C:\...\<appname>Attr.h(40) : error: expected ,, got linkHdr
BMAKE: call trace
    line:   84, C:\...\<appname>.mke
Mon Apr 22 15:26:07 2019, elapsed time: 0:02

typedef struct userDataHeader
{
    LinkageHeader    linkHdr;
    DSIDataHeader    dsiHdr;
} UserDataHeader;

What Include file or update do I need to make so that the MT file can be compiled to .r file

Thanks

Peter

  • Hi Peter,

    Please refer to the MicroStation CONNECT Examples: circuit and/or scanfile.

    Both examples use an .mt in their project make files.  For the .mt file: #include <RmgrTools\Tools\datadef.r.h>.

    Note in MicroStation CONNECT the distinction has been made to ensure .h files should be true native platform .h compatible, and any .r.h files treated and used as "resource header" files purposes only. 

    Given that, the .mke file compiles the .mt file (e.g. circuit) occurs like below:

    circuit.mke:50:$(genSrc)$(sAppName)typ.r : $(baseDir)$(sAppName)typ.mt \

    In your .cpp file including (#include <Mstn\MdlApi\MdlApi.h>) which is somewhat analogous to prior MDL practice of including "msvars.fdf" to include a large variety of headers commonly needed.

    Lastly, in MicroStation CONNECT you may want to try to use: SDKSearch <SearchTerm> def.  Where "def" can be used to narrow/filter search results to the most common form of definitions for a given search term.

    HTH,
    Bob



  • Hello Bob,

    The Circuit and Scanfile examples have the LinkageHeader in the CPP file not the .H file which is included to provide structure def for the .MT file.

    If I add the includes identified I get the following error:

    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(46) : error: "This file is for C++ compilands only"
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(11) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(12) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(13) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(14) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(16) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(17) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(18) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(19) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(28) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(33) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(39) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(40) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(41) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(43) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/suppress_warnings.h(44) : warning: pragma not recognized.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(70) : warning: macro ENUM_UNDERLYING_TYPE previously defined as .
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(112) : error: can't open #include file limits.h
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(112) : error: No such file or directory
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: Data declarations must be typedefs.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: expected ;, got BENTLEY_NAMESPACE_NAME
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: Data declarations must be typedefs.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: expected ;, got }
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: expected ;, got ::
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: expected ;, got ::
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: Data declarations must be typedefs.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(239) : error: expected ;, got }
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(240) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(240) : error: Data declarations must be typedefs.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(240) : error: expected ;, got }
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(240) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(240) : error: expected ;, got ::
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(240) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(240) : error: expected ;, got ::
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(240) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(240) : error: Data declarations must be typedefs.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(240) : error: expected ;, got }
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(241) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(241) : error: Data declarations must be typedefs.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(241) : error: expected ;, got }
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(241) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(241) : error: expected ;, got ::
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(241) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(241) : error: expected ;, got ::
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(241) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(241) : error: Data declarations must be typedefs.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(241) : error: expected ;, got }
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(242) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(242) : error: Data declarations must be typedefs.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(242) : error: expected ;, got }
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(242) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(242) : error: expected ;, got ::
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(242) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(242) : error: expected ;, got ::
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(242) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(242) : error: Data declarations must be typedefs.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(242) : error: expected ;, got }
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(243) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(243) : error: Data declarations must be typedefs.
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(243) : error: expected ;, got }
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(243) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(243) : error: expected ;, got ::
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(243) : error: bad declaration
    C:\PROGRA~1\Bentley\MICROS~2\include\Bentley/Bentley.h(243): Exceeded limit for errors.
    BMAKE: call trace

  • Hello Peter, 

    As mentions, there is a lot of changes with the handling of #inlude.

    We found out, best practice is to comment ALL old #include statements and "reinclude" what is necessary with the samples as guide.

    The #include handling is a lot different from V8, but in the end also a lot clearer, after you get familiar with its concept. 

    Mit freundlichen Grüßen / Best regards
    Volker Hüfner

    |  AB_DATE Engineering  Software   |  ab-date.de  |

  • What Include file or update do I need to make so that the MT file can be compiled to .r file

    Ask yourself the reason for the .mt file.  It contains very little except some #includes and the publishStructures directive.  It's job is to convert a C struct to a binary type interpretation stored in a .rsc file.  The type interpretation data is used by the Dialog Manager when passing information between your app. variables and your dialog items.  When the Dialog Manager sees "MyStruct.myVariable" in a dialog item access string it can figure out what type of data is in use and how to transfer data between that dialog item and your app. variable.

    The #includes are straightforward: the circuit example .mt has this...

    #include <RmgrTools/Tools/datadef.r.h>
    #include "circuitcomp.h"
    

    The first includes common Bentley definitions and the second includes the circuit app's own struct definitions...

    typedef struct batteryinfo
        {
        ...
        }BatteryInfo;
    
    typedef struct wireinfo
        {
        ...
        }WireInfo;
    
    typedef struct lightinfo
        {
        ...
        }LightInfo;
    
    typedef struct circuitinfo
        {...
        } CircuitInfo;    
    

    The type resource compiler has all the information it needs to convert those struct definitions in the header file to type resource definitions.  Other files, such as C++ implementation modules, can use those same structure definitions.

    What Include file or update do I need to make so that the MT file can be compiled to .r file

    Create a UserDataHeader.r.h file.  Write the struct definition in that file.  #include only those headers required to make it a valid definition.  Include UserDataHeader.r.h in your .mt file.  Include UserDataHeader.r.h in the C++ files that need it.

     
    Regards, Jon Summers
    LA Solutions

  • Hello Everyone,

    Thank you for taking the time to look at my issue. I created a .H file to add the structures which are not being located. When the .R file is compiled there is an error:

    {DTYPE_ENDSTRUCT,     1,            ,               DTYPE_LONG},

    TestIssue.r(23) : error: expected expression.

     

    I tried to create a test case:

    TestIssue.mke

    #--------------------------------------------------------------------------------------
    #     $Source:  $
    #
    #  $Copyright:  $
    #--------------------------------------------------------------------------------------
    #---------------------------------------------
    # Define macros specific to this example
    #---------------------------------------------
    PolicyFile = $(MDLMKI)MicroStationPolicy.mki
    
    appName = TestIssue
    
    baseDir         = $(_MakeFilePath)
    
    MDLMKI = $(MSMDE)mki/
    MDLINC = ${MSMDE}include/
    
    %include $(MDLMKI)mdl.mki
    #rCompOpts + -i$(MDLINC)
    cIncs + -I$(MDLINC)
    
    mdlLibs = $(MSMDE)library/
    
    #------------------------------------------------------------------------
    # Create & compile the app's type resource using rsctype & rcomp
    #------------------------------------------------------------------------
    $(baseDir)$(appName).r      : $(baseDir)$(appName).mt   
    
    $(baseDir)$(appName).rsc    : $(baseDir)$(appName).r
    
    

    TestIssue.mt

    #include <RmgrTools\Tools\datadef.r.h>
    
    #include    "TestIssue.h"     /*  */
    
    #pragma packedLittleEndianData
    
    createDataDef(ncitemlinkdata,        DSI_NCITEM_LINKAGE);
    

    TestIssue.h

    #include <RmgrTools\Tools\datadef.r.h>
    #include "Ustn_structures.h"
    #if !defined (resource)
    
    #define  DSI_NCITEM_LINKAGE         20
    
    typedef struct dsiheaderdata
    {
       UChar    appType;     // application element Type (max 256)
       UChar    subType;     // application sub class (max 256)
       UShort   elVersion;   // element version changes ONLY if/when this
    } DSIDataHeader;         // appType and subType's Data sturcture changes
    
    typedef struct userDataHeader
    {
       LinkageHeader    linkHdr;
       DSIDataHeader    dsiHdr;
    } UserDataHeader;
    
    typedef struct ncitemdata
    {
    #if defined (dsiRsc)
       short    buff[12];    // 24 total bytes for largest union member
    #else
       union {
          struct {
             int    isManualOrigin;
             int    originPanelType;
          } origin;
          char   panelId[8];
          char   dscrStr[21];
          char   buff[24];
       } u;
    #endif
    } NCItemData;
    
    typedef struct ncitemlinkdata
    {
       UserDataHeader    userHdr;
       NCItemData        ncData;
    } NCItemLinkData;
    
    #endif
    

    Ustn_Structures.h

     

    /*----------------------------------------------------------------------+
    |                                                                       |
    |   Linkage Header - Same for all element user data                     |
    |                                                                       |
    |   Use LinkageUtil::GetWords/setWords to get/set linkage size.           |
    |                                                                       |
    +----------------------------------------------------------------------*/
    struct LinkageHeader
    {
        UInt16      wdMantissa:8;           // mantissa words: wtf if wdExponent=0 
        UInt16      wdExponent:4;           // exponent for words multiplier       
        UInt16      user:1;                 // boolean: user data linkage          
        UInt16      modified:1;             // boolean: user linkage modified      
        UInt16      remote:1;               // boolean: remote linkage             
        UInt16      info:1;                 // boolean: informational linkage      
        UInt16      primaryID;              // User ID number                      
    };
    
    

    The test case creates a.R file and then tries to compile to a .RSC and there is an error because a field is empty.

    Any suggestions?

    Thanks

    Peter

  • Hi Peter,

    The test case creates a.R file and then tries to compile to a .RSC and there is an error because a field is empty.

    Why you do not share also the created .r file?

    I do not assume the problem is in this file, but when you say the error is reported when .r file is compiled and you do not share the file itself, it makes the discussion sources incomplete.

    Regards,

      Jan

  • Sorry for not including the file.

    #include <Mstn\MicroStation.r.h>
    #include <RmgrTools\Tools\datadef.r.h>
    #include <RmgrTools\Tools\cexprrsc.r.h>
    
    
    #pragma pushDataProps
    #pragma packedLittleEndianData
    DataDefBlock 20 = /*    struct ncitemlinkdata    */
    {
        {DTYPE_STRUCT,	4,	0,	DTYPE_LONG},
        {DTYPE_STRUCT,	2,	0,	DTYPE_SHORT},
        {DTYPE_STRUCT,	2,	0,	DTYPE_SHORT},
        {DTYPE_SHORT,	1,	ATTR_S_LE,	FIRSTMEM | S_ALIGN(DTYPE_SHORT) }, 	/*    */
        {DTYPE_SHORT,	1,	ATTR_S_LE,	0}, 	/*  primaryID  */
        {DTYPE_ENDSTRUCT,	1,	DTYPE_SHORT,	DTYPE_SHORT},
        {DTYPE_STRUCT,	2,	0,	DTYPE_SHORT},
        {DTYPE_CHAR,	1,	0,	FIRSTMEM | S_ALIGN(DTYPE_SHORT) }, 	/*  appType  */
        {DTYPE_CHAR,	1,	0,	0}, 	/*  subType  */
        {DTYPE_SHORT,	1,	ATTR_S_LE,	0}, 	/*  elVersion  */
        {DTYPE_ENDSTRUCT,	1,	DTYPE_CHAR,	DTYPE_SHORT},
        {DTYPE_ENDSTRUCT,	1,	DTYPE_SHORT,	DTYPE_SHORT},
        {DTYPE_STRUCT,	4,	0,	DTYPE_LONG},
        {DTYPE_ENDSTRUCT,	1,	,	DTYPE_LONG},
        {DTYPE_ENDSTRUCT,	1,	DTYPE_SHORT,	DTYPE_LONG}
    };
    
    DataSize 20 = { 32 }; 
    
    
    #pragma popDataProps
    

    The error is on line 23.

  • Hi Peter,

    Is Line #23 possibly missing a 2nd DTYPE_LONG where the empty comma is?

    Bob



  • Hello

    Yes that is what I think is missing. But that file should be generated, so the structure must have something missing?

    What change is required?

    Peter

  • Hi Peter just a guess, 

    I have some idea in the deep backside of my brain, there was trouble "UShort" and mt-files  Nothing concrete

    Maby you could try to replace UShort by some other writing of "unsigned short" 

    As I say, just some feeling ^_^

    Mit freundlichen Grüßen / Best regards
    Volker Hüfner

    |  AB_DATE Engineering  Software   |  ab-date.de  |