loading multiple versions of fbclient.dll

131 views
Skip to first unread message

Ján Kolár

unread,
Mar 11, 2025, 4:14:58 AM3/11/25
to firebird-support
Hi,
finally our company decided to migrate from FB 2.5 to FB 5.0. I have created upgrade utility for that process but I am stuck at one problem. My application which should work simultaneously with old and new databases cannot load multiple versions of library fbclient.dll. More precisely, problem is not with loading libraries which succeeds but with subsequent connection attempt. I can see in Process Explorer that my application loaded two versions of fbclient.dll from correct directories. If I first load fbclient.dll delivered with FB 5.0 and then fbclient.dll for FB 2.5 things seems to work. I am not satisfied with this solution because it is not robust. If I change load order so I first load fbclient.dll for FB 2.5 and after that fbclient.dll for FB 5.0, I cannot connect to FB 5.0 database. The connection attempt finishes with this error:

[FireDAC][Phys][FB]Error loading plugin ChaCha64
Module C:\Program Files (x86)\Firebird\Firebird_5_0\plugins\ChaCha exists but can not be loaded
The specified procedure could not be found. 

After analysing situation it seems to me, that plugin stored in external library chacha.dll calls LoadLibrary function without specifying path so for example:
LoadLibrary("fbclient.dll"). What then happens is fully documented by MSDN:

"If lpFileName does not include a path and there is more than one loaded module with the same base name and extension, the function returns a handle to the module that was loaded first.
When no path is specified, the function searches for loaded modules whose base name matches the base name of the module to be loaded. If the name matches, the load succeeds. Otherwise, the function searches for the file."

This is very unfortunate behaviour. For now I can solve it by loading fbclient.dll for FB5.0 first. In future if we support more than two versions of Firebird (for example FB 2.5, FB 5.0, FB 6.0) this solution may not work reliably. It would be better if external plugins used correct version of fbclient.dll using full path. So if fbclient.dll is stored in directory C:\Program Files (x86)\Firebird\Firebird_5_0, chacha.dll loaded from fbclient.dll should load fbclient.dll from this exact directory.

As a side note, we are using C++ Builder 12 with FireDAC library. We are not calling fbclient.dll functions directly.

Ján Kolár

Mark Rotteveel

unread,
Mar 11, 2025, 4:20:50 AM3/11/25
to firebird...@googlegroups.com
On 11/03/2025 07:52, Ján Kolár wrote:
> finally our company decided to migrate from FB 2.5 to FB 5.0. I have
> created upgrade utility for that process but I am stuck at one problem.
> My application which should work simultaneously with old and new
> databases cannot load multiple versions of library fbclient.dll. More

Why are you even loading two fbclient libraries: *if* you're using
TCP/IP connections (not 100% sure about XNET), then you can simply use
the newest: the protocol is versioned, and fbclient of Firebird 5 can
talk to Firebird 1 and higher.

And even if you could, as far as I'm aware, you'd still be using the
entrypoints of the first version loaded.

> precisely, problem is not with loading libraries which succeeds but with
> subsequent connection attempt. I can see in Process Explorer that my
> application loaded two versions of fbclient.dll from correct
> directories. If I first load fbclient.dll delivered with FB 5.0 and then
> fbclient.dll for FB 2.5 things seems to work. I am not satisfied with
> this solution because it is not robust. If I change load order so I
> first load fbclient.dll for FB 2.5 and after that fbclient.dll for FB
> 5.0, I cannot connect to FB 5.0 database. The connection attempt
> finishes with this error:

> [FireDAC][Phys][FB]Error loading plugin ChaCha64
> Module C:\Program Files (x86)\Firebird\Firebird_5_0\plugins\ChaCha
> exists but can not be loaded
> The specified procedure could not be found.
>
> After analysing situation it seems to me, that plugin stored in external
> library chacha.dll calls LoadLibrary function without specifying path so
> for example:
> LoadLibrary("fbclient.dll"). What then happens is fully documented by MSDN:
>
> "If /lpFileName/ does not include a path and there is more than one
> loaded module with the same base name and extension, the function
> returns a handle to the module that was loaded first.
> When no path is specified, the function searches for loaded modules
> whose base name matches the base name of the module to be loaded. If the
> name matches, the load succeeds. Otherwise, the function searches for
> the file."

There is no other solution, because hardcoding a path would make it
impossible to move the file or install in a different location.

> This is very unfortunate behaviour. For now I can solve it by loading
> fbclient.dll for FB5.0 first. In future if we support more than two
> versions of Firebird (for example FB 2.5, FB 5.0, FB 6.0) this solution
> may not work reliably. It would be better if external plugins used
> correct version of fbclient.dll using full path. So if fbclient.dll is
> stored in directory C:\Program Files (x86)\Firebird\Firebird_5_0,
> chacha.dll loaded from fbclient.dll should load fbclient.dll from this
> exact directory.

Again, you don't need to load multiple versions of fbclient, and in
practice, as far as I'm aware, you would still be using the one that was
loaded first.

Mark
--
Mark Rotteveel

Dimitry Sibiryakov

unread,
Mar 11, 2025, 4:36:21 AM3/11/25
to firebird...@googlegroups.com
Ján Kolár wrote 11.03.2025 7:52:
> If I first
> load fbclient.dll delivered with FB 5.0 and then fbclient.dll for FB 2.5
> things seems to work.

I wonder how have you managed to make FireDAC to use different client
libraries for different connections? I know no way for this.

> After analysing situation it seems to me, that plugin stored in external
> library chacha.dll calls LoadLibrary function without specifying path so
> for example:
> LoadLibrary("fbclient.dll").

No plugin ever need to load fbclient.dll. Either your analyse is wrong or it
is a bug in ChaCha plugin.

--
WBR, SD.

Ján Kolár

unread,
Mar 11, 2025, 5:00:03 AM3/11/25
to firebird...@googlegroups.com

Hi Dimitry,

 

Its possible to set path to client library using property VendorLib of database driver.

 

   TFDConnection *conn = ...

   ...

   Firedac::Phys::Fb::TFDPhysFBDriverLink *driver = new Firedac::Phys::Fb::TFDPhysFBDriverLink(conn);

   String name = L"Driver";

   name += instanceName;

   name.cat_printf(L"_%d", ++this->driverId);

   driver->Name = name;

   String driverId = name;

   LOG_TRACE(L"Creating new driver '%s' ...", driverId);

   driver->DriverID = driverId;

   driver->VendorLib = "C:\Program Files (x86)\Firebird\Firebird_5_0\fbclient.dll";

   conn->DriverName = driver->DriverID;

 

Its documented here:

https://docwiki.embarcadero.com/RADStudio/Sydney/en/Configuring_Drivers_(FireDAC)

 

S pozdravom / Best regards,

Jan KOLAR


--
Support the ongoing development of Firebird! Consider donating to the Firebird Foundation and help ensure its future. Every contribution makes a difference. Learn more and donate here:
https://www.firebirdsql.org/donate
---
You received this message because you are subscribed to a topic in the Google Groups "firebird-support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/firebird-support/pUNNvx3ZD3Y/unsubscribe.
To unsubscribe from this group and all its topics, send an email to firebird-suppo...@googlegroups.com.
To view this discussion, visit https://groups.google.com/d/msgid/firebird-support/03ded374-ef3c-477d-8315-d63d1e78004a%40ibphoenix.com.

ja...@jac2.co.uk

unread,
Mar 11, 2025, 5:23:08 AM3/11/25
to firebird...@googlegroups.com

 

You can introduce a new “driver link”, give it a name and then associate:

 

object FDPhysFBDriverLinkFB15: TFDPhysFBDriverLink

  DriverID = 'FB15'

  VendorLib = '….\gds32.dll'

  Left = 248

  Top = 64

End

 

object FDConnectionFBSrc: TFDConnection

  Params.Strings = (

      'Database=<snip>

    'SQLDialect=1'

    'DriverID=FB15')

  ConnectedStoredUsage = []

  LoginPrompt = False

  Transaction = FDTransaction1

  BeforeConnect = FDConnectionFBSrcBeforeConnect

  Left = 224

  Top = 120

End

 

I would name the dll’s different names (unlike my example of gd32.dll, maybe fbclient1_5.dll.

 

What I don’t  know is how it would handle distributed transactions – I haven’t tested this (or in fact multiple fbclients being loaded at the same tim).

 

 

Jason Chapman

JAC2 Consultancy Limited

You received this message because you are subscribed to the Google Groups "firebird-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebird-suppo...@googlegroups.com.
To view this discussion, visit https://groups.google.com/d/msgid/firebird-support/CACgRJNmwMDUrq2_cD8Jp1dfXrYrmV-558QoFXz%3DRsq0kX5%3Dyww%40mail.gmail.com.

Elmar Haneke

unread,
Mar 11, 2025, 6:58:09 AM3/11/25
to firebird...@googlegroups.com
finally our company decided to migrate from FB 2.5 to FB 5.0. I have created upgrade utility for that process but I am stuck at one problem. My application which should work simultaneously with old and new databases cannot load multiple versions of library fbclient.dll.

In theory it should be possible to utilize different fbclient.dll in the same process. 

In practice this is required only in embedded mode since newer lib can connect to older server.

For later updates this should not be required again since v5 lib can access v3/v4 files by adding the engine-plugin from old version.

For reading FB25 databases there is a closed source plugin available to access them from newer fbclient.dll. This might be a less complicated alternative for your conversion.

For better separation you should place old and new stuff into different subdirectories.

As FireDAC is a multi DB lib there is a chance to get old and new separated.

For my own transitions I did not try to go that way and made the conversion by doing backup and restore. You can place all files required for v2.5 backup into subdirectory and run backup there. Afterward restore from v5 directory.

Elmar


Mark Rotteveel

unread,
Mar 11, 2025, 7:53:22 AM3/11/25
to firebird...@googlegroups.com
On 11/03/2025 11:57, Elmar Haneke wrote:
> For later updates this should not be required again since v5 lib can
> access v3/v4 files by adding the engine-plugin from old version.

For v4 that isn't even necessary, as Firebird 5 can read the ODS of
Firebird 4. Nor is it possible without renaming things, because the
engine plugin has the same name.

Mark
--
Mark Rotteveel

Norldir Kunkel

unread,
Mar 12, 2025, 7:37:16 AM3/12/25
to firebird-support

Hi Ján Kolár,

We resolved this by sending our customers the Firebird 5 DLL, renamed as firebird500.dll (including all dependencies), and configuring the system to use this DLL.

Customers using Firebird 2.5.9 and customers using Firebird 5.x connect through firebird500.dll, and everything works fine.

Best regards,
Norldir Kunkel.


Reply all
Reply to author
Forward
0 new messages