Is there a way to split the _Intf file in multiple ones?

Hello there,

I have just got a linker error on C++Builder 10.1 when trying to compile a BPL that includes the _Intf generated by RemObjects. The error reads:

[ilink32 Error] Fatal: Exceeded memory limit for block Line number cache in module …\Server\msaCI_Intf.cpp

Apparently the file is too big for the linker to process (around 78k lines). I have moved forward disabling the Debug info for that BPL, but that’s not optimal of course (and also, doesn’t fix the issue, just delays it).

So, I wonder if there is a way to split the _Intf in several ones?

The RODL definition is, I presume, not something overly complicated nor extense. And there are still several things and methods I will have to add to it on the life of this project…

Thanks!

you can split your RODL to several small RODLs :

original_RODL --> rodl1
              |-> rodl2
              |-> rodl3

or

original_RODL -> rodl3 -> rodl2 -> rodl1

it depends on your logic

final RODL should use all these RODLs:
Untitled

you can add existed RODL via
Untitled

Ok, great.

I will change my RODL to separete it in several ones using your instructions.

Thanks!

Hello Evgeny,

I haven’t had the time to try your suggestion, but ASAP I will try and see if it manages to overcome this problem.

For now I’ve just put the _Intf code on a specific BPL with debugging disabled, and I’m using it from the main project without issues (except that I have to change for every change one of the functions generated to be exported, but I will put that in another post). I rarely need to debug the _Intf code so it’s a minor inconvenience.

Hello Evgeny,

I just tried today what you mentioned… it works, with some caveats.

  1. The most important one is: the DefaultNamespaces() function in the _Intf of the “final” RODL loads the DefaultNamespace of the included RODLs, but in C++Builder at least it does not use the correct namespace identifier (specified in the RODL) for that variable, instead it uses the name of the file (as if it were Delphi). This produces a compile time error, an easy one to solve but ever time the unit is regenerated it needs to be manually fixed.
  2. There is a checkbox in Service Builder for the used RODL that says Generate Code for the definitions of this RODL file. I don’t know what it does as for C++Builder at least it doesn’t seem to do anything. I have to generate the code for each RODL file manually.
  3. If you do not change the namespaces for each RODL then, at least in C++Builder, you end up with compile time errors as the consts defined in the _Intf.h file for LibraryUID, DefaultNamespace and TargetNamespace have the same name in every _Intf. What’s the correct way to handle this? A single namespace for the whole “solution” or it is as designed to have a different namespace for each RODL?

This is all with 9.2 (I haven’t had the time to try again with 9.3) but I am guessing this hasn’t changed between versions.

Thanks for your help

I can reproduce it.
it generates code in delphi style, i.e. *_Intf::DefaultNamespace instead of namespace::DefaultNamespace.
as a temporary workaround, you can disable autoregeneration files via adding a dot , like:

//#.ROGEN:Project80.rodl | RemObjects: Careful, do not remove!

this checkbox is designed for IDE support. in Service Builder it has no effect for generation of files.

it’s up to your design, but if one namespace is used in several rodls, above constants will be generated in each _intf.
ofc, you can uncheck Generate Code for the definitions of this RODL file so code from used RODLs won’t be regenerated at compiling project.

I think, we also can solve this issue via generating code like

#ifndef myns_definition
  #define myns_definition
  const System::UnicodeString LibraryUID = "{5EDD1F6A-3A01-4881-8D6D-4FBF93FA247C}";
  const System::UnicodeString DefaultNamespace = "myns";
  const System::UnicodeString TargetNamespace = "myns";
#endif

Hello Evgeny,

Thanks for the reply.

I actually have the RODL code regeneration disabled most of the time, so it’s not a big problem to fix this manually every time it needs to be regenerated.

About the different namespaces: I had to change the namespaces of the RODLs to avoid this issues, but then I had to fix the types in my project to include the new namespace. Not a big deal and this is because it was not designed from the beginning to be different RODLs. Still, it might be better to have those 3 consts, LibraryUID, and so on, with a name specific for each RODL? Another option is to move those consts to the .cpp part (where they are currently used), but I don’t know if you produce them in the .h in case they need to be consumed outside that unit.

The #ifndefsoultion you propose would work fine for different RODLs sharing the same namespace, but the LibraryUID woudl be lost, isn’t it? (as each RODL needs to have it’s own UID?)

On a related note, I saw a new thing on the code generated for the _Impl with version 9.2: there is a #define on the _Impl.h generated file for __ServiceName. This will be problematic if one needs to use different _Impl.h in another unit, as the name of the identifier will be the same. Worse: IIRC, #defines are not namespaced’ so even if the units have different namespaces it won’t matter.

Previous generated _Impl didn’t have that #define, instead it used the value directly on the CPP file.

Thanks

LibraryUID is required for identification of RODL so it isn’t used in runtime by us but it can be used by user in some purposes.

I’ll review this case

fixed. now correct namespace is generated

fixed. __ServiceName wasn’t generated for C++Builder anymore