[CONNECT C++] Calling undocumented function dgnFileObj_getHighestElementID

Hi,

   in the Connect edition: is there any way, how to call undocumented function like: 

unsigned __int64 Bentley::dgnFileObj_getHighestElementID(struct Bentley::DgnPlatform::DgnFile *)

from DgnPlatform.lib (dgnFileObj_getHighestElementID@Bentley@@YA_KPEAUDgnFile@DgnPlatform@1@@Z)?

my .fdf looks like that:

BEGIN_BENTLEY_NAMESPACE

unsigned __int64 dgnFileObj_getHighestElementID(struct Bentley::DgnPlatform::DgnFile*);

END_BENTLEY_NAMESPACE

when i try to call, an (linker) error appears:

Error LNK2028: unresolved token (0A0000DA) "extern "C" unsigned __int64 __cdecl dgnFileObj_getHighestElementID(struct Bentley::DgnPlatform::DgnFile *)" (?dgnFileObj_getHighestElementID@@$$J0YA_KPEAUDgnFile@DgnPlatform@Bentley@@@Z) referenced in function "public: virtual __int64 __clrcall Hsi::Asw::Interop::Graphics::Model::GetHighestElementId(void)" (?GetHighestElementId@Model@Graphics@Interop@Asw@Hsi@@$$FUE$AAM_JXZ)

Error LNK2019: unresolved external symbol "extern "C" unsigned __int64 __cdecl dgnFileObj_getHighestElementID(struct Bentley::DgnPlatform::DgnFile *)" (?dgnFileObj_getHighestElementID@@$$J0YA_KPEAUDgnFile@DgnPlatform@Bentley@@@Z) referenced in function "public: virtual __int64 __clrcall Hsi::Asw::Interop::Graphics::Model::GetHighestElementId(void)" (?GetHighestElementId@Model@Graphics@Interop@Asw@Hsi@@$$FUE$AAM_JXZ)

thanks for any idea.

Best regards

Jan

  • is there any way, how to call undocumented function

    Generally, undocumented functions are not supported: don't use them.  That is, it's signature could change, it might be dropped in favour of something else, or it could become forgotten and broken if not used for anything by MicroStation.

    MicroStation allocates object IDs automatically.  We can't assign them: only read them.

    Having provided that cautionary note, I ask why you want to use dgnFileObj_getHighestElementID()?

    Compiler or Linker Error?

    You ask how to call that function, which you've done successfully: you don't have a C++ compiler error.  The errors you have posted (LNK2028 and LNK2019) are from the C++ linker, not the compiler.  The message is clear: the linker can't find the definition of the function.  That is, the compiled binary code was not found.

    You'll have to search the delivered library (*.lib) and implementation (*.dll) files to find it.  How do you do that?  That question has been asked and answered many times.  Search web sites that deal with Microsoft technology.  Here's one example.

     
    Regards, Jon Summers
    LA Solutions

  • Hi Jan,

    in the Connect edition: is there any way, how to call undocumented function like: 

    I think there is no way to call this function: I do not see it published in ustation.dll (where I would expect it is available).

    thanks for any idea.

    I agree with Jon: To use undocumented functions is generally bad idea. I recall only one case when it makes sense (because similar functionality is not exposed directly by API and at the same time, it does not break any concept or rule).

    Similarly to Jon: Why do you need to call this function? How it can be used, when only MicroStation decides, what id will be used next?

    To know the highest element id in a specific model, to iterate all elements is simple (and very fast) way. But it does not tell the highest element id in the whole DGN file.

    With regards,

      Jan

  • Thanks Jon, Jan .. we use this function in v8i for getting highest element id in model for our non graphic data solution purposes. Now we migrate to CE, so i must solve this in our core layer API.  

    I think there is no way to call this function: I do not see it published in ustation.dll (where I would expect it is available).

    Jan, the funcion is published in the DgnPlatform5.dll  (+  DgnPlatform.lib), but i cannot find a way to define right fdf, without getting a linker error. In the v8i it was (and it works):

    ElementID dgnFileObj_getHighestElementID(DgnFileObjP pFile);

    ..anyway, it seems like here is a problem , in CE .. 

    Thanks a lot

    Jan

  • Hi Jan,

    Jan, the funcion is published in the DgnPlatform5.dll  (+  DgnPlatform.lib)

    oops, I missed this information (and did not fined it in dll/lib).

    but i cannot find a way to define right fdf, without getting a linker error

    I am not very good in export/import C functions issues, but what about something like

    BEGIN_BENTLEY_NAMESPACE
    
    BEGIN_EXTERN_C
    
    MSCORE_EXPORT ElementId dgnFileObj_getHighestElementID(DgnFileP dgnFileObj);
    
    END_EXTERN_C
    
    END_BENTLEY_NAMESPACE

    Linker errors and warnings are often fuzzy, but it looks like that lib declaration and what is reported by linker use different decoration styles, which can be caused by wrong calling convention setting.

    we use this function in v8i for getting highest element id in model for our non graphic data solution purposes.

    It sounds a bit weird and in my opinion wrong, because it depends on format implementation feature, but it's not fair to see V8i implementation from CE API perspective (where much more functionality, in OOP style and elegant, is available).

    I thing the discussed function does not return the highest id in model, but in DGN file, which is something different (the same when only one model is used). But, of course, it does not lead to any issue or ids duplication.

    To find the highest id in model is simple, and even when every element id has to be checked, I assume it's very fast even for large files. But of course, when there is specialized function available, why to iterate the whole model  ;-)

    Regards,

      Jan

  • Is there any way, how to call undocumented function?
    The funcion is published in the DgnPlatform5.dll 

    So the function is published but undocumented!  It's best to reveal all details in your initial post.

    Use the Microsoft tools I mentioned to see the exports in that DLL.  Your  file must include the DLL/library for the linker.

    it looks like that lib declaration and what is reported by linker use different decoration styles

    That could cause the problem.  If looks at the exported functions in the DLL, it will show him the decorated C++ function name.

     
    Regards, Jon Summers
    LA Solutions

  • Thans Jan, i have tried a lot of variant fdf style (including your - advice -one), but still no success.. thanks Jon too.. yes, it seems like there is a namespace problem,

    in the dll file is:

    unsigned __int64 Bentley::dgnFileObj_getHighestElementID(struct Bentley::DgnPlatform::DgnFile *)
    
    
    

    in the lib file (after decoding) is:

    unsigned __int64 __cdecl Bentley::dgnFileObj_getHighestElementID(struct Bentley::DgnPlatform::DgnFile * __ptr64) 

    but linker mentions just function name (without the namespace)... so i try to use a decorating style with namespace, unfortunatelly i dont know how to define it right..(maybe it just doesn't work at all).  I know that using undocument funcion is not good practice, this case was used probably to avoid a model scanning ..  so thanks for your time, I don't want to hold on anymore ;) regards Jan

  • when i try to call, an (linker) error appears

    When you try to call that function, the compiler accepts your function declaration.  You don't have a problem calling that function, but the C++ linker can't find it.

    You told us in your other thread that the function is in DgnPlatform5.  Have you put in your bmake file the instruction to link with that library?  That statement would be something like...

    LINKER_LIBRARIES            + $(mdlLibs)DgnPlatform5.lib

    Where mdlLibs is the folder where the SDK library files are located.

     
    Regards, Jon Summers
    LA Solutions

  • Have you put in your bmake file the instruction to link with that library?

    yes, library DgnPlatform.lib (DgnPlatform5.lib does not exist) is added

    we have tried to figure it out  without usising this undocumented function,,,

    anyway, if someone manages to solve this problem, it will be fine .. it's not hard to try it on your own example. Unfortunately, now I don't have time for further attempts. Thanks again for your insights. 

    best regards Jan

  • Hi Jan,

    we have tried to figure it out  without usising this undocumented function,,,

    it depends whether you are interested in the highest element id used in specific (e.g. active) model, or in the whole DGN file.

    I think (but I am not sure whether I remember it right), DGN file "knows" this information, because the highest element id is stored in DGN file header, and MicroStation keeps and updates this information during a session. But it's not exposed to public API.

    anyway, if someone manages to solve this problem, it will be fine ..

    Because I do not recall similar discussion, I am afraid when anybody will try to solve it, it will be for a joy (and self-study) only, not for real reason. I am still thinking that to know the highest element id is internal information, depending on persistence implementation, not useful anywhere.

    Regards,

      Jan

  • Hi ,

    we use this function in v8i for getting highest element id in model for our non graphic data solution purposes.

    As others suggested, using an unpublished function is not highly recommended.

    Unfortunately this response does not provide enough insights into the problems/challenges (tasks/workflows) your code is attempting to resolve. If you could expand a bit on the conditions/workflows for why you (think you may) need to call dgnFileObj_getHighestElementID we may be able to provide the best recommendation possible. Using that function you (and your app) can get some unexpected results quickly (or what may appear sporadically) if you are not careful.

    I suspect you are attempting to use a ForeignID to map to MicroStation ElementIDs; where if a user uses any Bentley product tools to modify those elements; the ElementID (unfortunately) is not a contract that the same element/component will maintain that exact same ID for the complete lifecycle of the component's life; and in a number of cases/workflows *will* be reassigned.  If you do have your own component id solution (a.k.a. a ForeignID) that you wish to ensure consistently correct MicroStation component element IDs will be returned, I suggest taking a look at the MicroStationAPI.chm help file topic: ElementIDMap (Header: include\DgnPlatform\ElementIdMap.h). Although the SDK currently does not provide an example for this API, there is a very helpful code snippet in the help topic ElementIDMap (See: Detailed Description).

    For the signature of an unpublished function you need to ensure an exact/correct function signature is being declared and provided. Otherwise the declaration though looking correct is still likely never be called. From your results, the .DLL output would appear closest to what the underlying declaration (if properly qualified w/MicroStation - namespaces and types) would likely look something like:

    ElementId Bentley::dgnFileObj_getHighestElementID (DgnFileP pFile)

    So, let me know if ElementIDMap is the solution you are really looking to implement, or some more information related to your workflows related to calling dgnFileObj_getHighestELementID; in case other options/solutions may be available.

    HTH,
    Bob