Solved

LoadPackage() question

Posted on 2002-03-26
10
382 Views
Last Modified: 2010-04-04
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,

Dave
 
0
Comment
Question by:largeone
  • 6
  • 4
10 Comments
 
LVL 6

Expert Comment

by:DrDelphi
ID: 6896474
Dave,
  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!!
0
 

Author Comment

by:largeone
ID: 6896505
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?
0
 
LVL 6

Expert Comment

by:DrDelphi
ID: 6896528
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!!
 


0
 

Author Comment

by:largeone
ID: 6896722
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.    
0
 
LVL 6

Expert Comment

by:DrDelphi
ID: 6896839
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.


NOTE:
  WHAT FOLLOWS PRESUMES STATICALLY LINKED PACKAGES!!
  ===================================================


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.

0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 6

Expert Comment

by:DrDelphi
ID: 6896861
"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!


0
 

Author Comment

by:largeone
ID: 6896912
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).
0
 
LVL 6

Accepted Solution

by:
DrDelphi earned 300 total points
ID: 6897050
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!!
0
 

Author Comment

by:largeone
ID: 6897201
Thanks!  I think I'm on my way now.  


Increased points to 350.
0
 
LVL 6

Expert Comment

by:DrDelphi
ID: 6897218
Cheers.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now