LoadPackage() question

I actually develop in BCB4, but I think the issues are the same as they would be in Delphi.  So here goes...

In an attempt to modularize our application, we're trying to build individual packages for different components of the program.  I currently have a calling application that consists only of a MDI parent form, and a base TMainMenu.  I also have a package that contiains a TMainMenu that merges with the parent, as well as a couple of MDI child forms.  There is another package that is intended to hold only a class that will provide access to a set of static variables(ApplicationDBPointer/SessionPointer, LogonID and other such things).

The problem I'm encountering is that much of the code our objects are built with relies on a .LIB  that our company has been using and building for years.  The only way that I've successfully been able to build these packages is to include this .LIB in the project.  When I do this, I get a
runtime error when trying to load a second package from the calling application (using LoadPackage( )).  It's telling me that it can't load the second package because the first (loaded) package already contains one of
the units from the .LIB.

Unloading the frist package before loading the second is not really an option.

My guess is that I have a setting(s) wrong somewhere.  

I'd really appreciate any information that could point me in the right direction.

Thank you,

Who is Participating?

Improve company productivity with a Business Account.Sign Up

DrDelphiConnect With a Mentor Commented:
The easiest thing would probably be to make a single package which includes the .LIB as opposed to two seperate ones.

 Failing that, (assuming you have access to all the code necessary), would be to recompile the .LIB file into a bpl which you could include in your requires.

Good luck!!
  I suspect that you in fact DON'T have anything wrong, but rather have to go back and retool the packages to prevent duplication of units in Requires between the two. You can't load a package twice in the IDE, including in the requires of another package.

Good luck!!
largeoneAuthor Commented:
I'm not quite sure I follow you Doc.

In my situation, I'm getting the message "Cannot load package B because it contains unit 'LibMisc' which is already contained in package A".  This 'LibMisc' unit is part of the .LIB mentioned above.  Are you saying that I need to scrap the .LIB and break out the individual units it contains and include them in each of my package projects individually?
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

not at all.... what you WILL need to do is to redesign either the packages so that only one of them includes the .LIB
Apart from that, then yes, you would need to retool the .LIB, most likely breaking it into two seperate files, each with requires that are mutually exclusive.

For my money, the first option is easiest, but you'll have to make that judgement call for yourself.

Good luck!!

largeoneAuthor Commented:
Boy, that is not the answer I wanted to hear!  

I'm still confused though.  I find it dificult to believe that concurrent packages can't use the same objects.  It seems to me by this logic that two packages couldn't use TForm or TEdit simultaneously, and that just makes no sense at all!

My sitiation gets much more complicated if ths is the case.  We have an inheritance tree of repository objects that our data windows are built upon that also rely on this .LIB.  I don't know how we would go about having data windows in different packages now.  Do we need to turn these into components...or maybe design time packages?  

We have a design time package (ExtraControls.bpi) that each of my packages 'requires' for compilation.  I haven't gotten any conflicts with this yet.    
From the Delphi help file on Packages (sorry, no BCB at the office)

Working with packages:

A package is a special dynamic-link library used by Delphi applications, the IDE, or both. Runtime packages provide functionality when a user runs an application. Design-time packages are used to install components in the IDE and to create special property editors for custom components. A single package can function at both design time and runtime, and design-time packages frequently work by calling runtime packages. To distinguish them from other DLLs, package libraries are stored in files that end with the .BPL (Borland package library) extension.

Like other runtime libraries, packages contain code that can be shared among applications. For example, the most frequently used Delphi components reside in a package called VCL50. Each time you create an application, you can specify that it uses VCL50. When you compile an application created this way, the applications executable image contains only the code and data unique to it; the common code is in VCL50.BPL. A computer with several package-enabled applications installed on it needs only a single copy of VCL50.BPL, which is shared by all the applications and the IDE itself.

Delphi ships with several precompiled runtime packages, including VCL50, that encapsulate VCL components. Delphi also uses design-time packages to manipulate components in the IDE.
You can build applications with or without packages. However, if you want to add custom components to the IDE, you must install them as design-time packages.
You can create your own runtime packages to share among applications. If you write Delphi components, you can compile your components into design-time packages before installing them.


The Requires clause

The requires clause specifies other, external packages that are used by the current package. An external package included in the requires clause is automatically linked at compile time into any application that uses both the current package and one of the units contained in the external package.
If the unit files contained in your package make references to other packaged units, the other packages should appear in your packages requires clause or you should add them. If the other packages are omitted from the requires clause, the compiler will import them into your package implicitly contained units.

Note:      Most packages that you create will require VCL50. Any package that depends on VCL units (including SysUtils) must list VCL50, or another package that requires VCL50, in its requires clause.

Avoiding circular package references

Packages cannot contain circular references in their requires clause. This means that

A package cannot reference itself in its own requires clause.
      A chain of references must terminate without rereferencing any package in the chain. If package A requires package B, then package B cannot require package A; if package A requires package B and package B requires package C, then package C cannot require package A.

Handling duplicate package references

Duplicate references in a packages requires clauseor in the Runtime Packages edit boxare ignored by the compiler. For programming clarity and readability, however, you should catch and remove duplicate package references.

The Contains clause

The contains clause identifies the unit files to be bound into the package. If you are writing your own package, put your source code in PAS files and include them in the contains clause.

Avoiding redundant source code uses

A package cannot appear in the contains clause of another package.
All units included directly in a packages contains clause, or included indirectly in any of those units, are bound into the package at compile time.
A unit cannot be contained (directly or indirectly) in more than one package used by the same application, including the Delphi IDE. This means that if you create a package that contains one of the units in VCL50, you wont be able to install your package in the IDE. To use an already-packaged unit file in another package, put the first package in the second packages requires clause.

"Duplicate references in a package’s requires clause—or in the Runtime Packages edit box—are ignored
by the compiler."

-Non applicable to a dynamically loaded package.

"A unit cannot be contained (directly or indirectly) in more than one package used by the same application,
including the Delphi IDE"

-Package1 loads with your .LIB file (and some source files therein), then Package2 tries to load that same .LIB (and source files) again... Boom!

largeoneAuthor Commented:
Thanks.  That was very thorough, and I don't know why BCB doesn't have the same info in it's help files...maybe I'm just not hitting it.

So what I'm getting from the above info is that I need to put package1.bpi in my package2 'requires' list...does that make sense?

Or maybe turn that .LIB into a .bpi and put it in all of my packages 'requires' lists?  

I'll throw some more points on top if you can tell me how to generate my .bpi(s).
largeoneAuthor Commented:
Thanks!  I think I'm on my way now.  

Increased points to 350.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.