tags:

views:

617

answers:

2

I have a Delphi application that I have written a fairly simple wrapper .exe for.

Basically, there was a dll that had a bunch of functions, one of which I would call iteratively once my wrapper did what it needed to. I am not in control of this dll file, and will never be.

Well, now this DLL is a BPL, and I'm not sure how to call functions within that file. Thanks in advance.

+2  A: 

A BPL is just a DLL with a few specific additions to it. You should have no trouble calling functions from it just like you did with the DLL, with one specific caveat: The BPL has to be built in the same version of Delphi as you're using. This can be a major drawback if you don't have the source code. If this is a problem for you, you should probably talk with whoever created it and ask them to make it back into a DLL.

Mason Wheeler
-1, I strongly disagree with the 'Back to DLL-Hell' idea. BPL's offere a very rich interface, and transparent memory management.
Henk Holterman
Whether or not you like the implications of it doesn't change the objective fact that you can't load a BPL from a Delphi executable compiled with a different version of Delphi. If you know a way to do so, I'd be *very* interested in knowing how...
Mason Wheeler
BPLs can certainly be built with a different Delphi version, if one sticks to the DLL interface and DLL-compatible types (no strings for a start).
mghie
Yes, but you know what I mean. A way to use the extended BPL features from a different Delphi version. AFAIK it can't be done.
Mason Wheeler
Mason, A BPL offers a DLL interface plus, if you use the right Delphi, Objects, Interfaces and all other Delphi types. Delphi's version policy is a bit of a pain but well known, just upgrade or downgrade.
Henk Holterman
Henk: Yes, that's exactly what I was saying. The problem is that using a BPL supplied by a third party leaves you tied to that version and unable to upgrade or downgrade unless they do too. This is why why no experienced Delphi developer uses binary-only component packages, for example.
Mason Wheeler
Henk, merely using DLLs does not create "DLL hell." If it did, then BPLs would be no different anyway, since they are DLLs. Nor does using packages solve any of the problems that occur in DLL hell. DLL hell is the problem of managing conflicting versions of a DLL in a single install location. You can just as easily have conflicting versions of a BPL.
Rob Kennedy
Rob, you are right about the general meaning of DLL-Hell, I used the term thinking about the effort it requires to transfer a simple string or array of records. And BPL's do solve most of those DLL problems.
Henk Holterman
+7  A: 

The easy way to use functions from a package is to "use" the unit that contains the function, call it as usual, and put the package on the list of your project's runtime packages. For that to work, there are a few requirements:

  1. Your project must use the same Delphi version as was used to compile the package.
  2. You must have access to the DCU file for the unit, or at least the DCP file for the package.
  3. The package must exist in the operating system's search path when your program starts.

If you can't satisfy the third requirement, or if you don't want to have the package loaded all the time, then you can call LoadPackage for it instead. The way to make that work is to have another package that is loaded all the time. It will be used by both your project and the package you wish to load. The intermediate package will expose an interface (such as some registration functions, a variable, or a class) that the main package can use to tell the application what its functions are. You won't be able to "use" the main package's unit in your application directly.

If you can't satisfy the first two requirements, then there is the much harder way, which is also what you'd need to do if your application isn't written in Delphi or C++ Builder. Treat the package like an ordinary DLL. Load it with LoadLibrary. Use GetProcAddress to load its Initialize function, and then call it. (Remember that the calling convention is register, not stdcall.) Then load the address of the function you wish to call, keeping in mind that the name of the function has been mangled to include some unit and type information. Call the Finalize function before you call FreeLibrary. Check the source for LoadPackage and UnloadPackage; whether you need to call CheckForDuplicateUnits probably depends on whether you can satisfy requirement number 1.

Rob Kennedy
Any way you can point me to a resource for doing this? I'm actually not a Delphi programmer, so I'm at a loss for some of this stuff.
Dan
I'm not aware of any resources describing how to "manually" load packages the way I outlined in the final paragraph. The normal way of using packages, as described in the penultimate paragraph, is something I'd expect to appear in the Delphi help, although I can't check that myself since I don't have Delphi installed anywhere.
Rob Kennedy