14

I have a Delphi application similar to Taskbar Shuffle that includes a hook dll.

EDIT: This hook DLL communicates with the main app by sending windows messages.

I want to add support to XP and Vista x64 and my initial idea was to convert the dll to 64-bit (compiling it with FreePascal) but keep the application 32-bit for now (Delphi).

Is it possible for a 32-bit application to access a 64-bit dll?

EDIT2: I'm loading the dll via LoadLibrary so I guess I'm stuck since a 32-bit process won't be able to load a 64-bit dll, according with what I read on the link pointed by Lars Truijens on one of the answers below.

smartins
  • 3,658
  • 7
  • 37
  • 53

4 Answers4

9

As long as the 64-bit DLL is being loaded by a separate 64-bit process, and all communication between 32-bit process and 64-bit DLL is via loose-coupled IPC-like mechanisms that the OS can marshall, then yes you can do that.

I've done something similar. A 32-bit application needed a custom Print Spooler add-in implemented in a DLL. The app and the spooler add-in communicated via IPC mechanisms (a fancy way of saying temporary files, in this case).

On 64-bit systems everything about the 32-bit application worked fine except that the Print Spooler refused to load the add-in DLL, because the Print Spooler was of course a 64-bit process.

The solution was as simple as rebuilding only the Spooler add-in in 64-bit. No need to change the entire 32-bit app.

Daniel Earwicker
  • 108,589
  • 35
  • 194
  • 274
  • I'm loading the dll via LoadLibrary so I guess I'm stuck since a 32-bit process won't be able to load a 64-bit dll, according with what I read on the link pointed by Lars Truijens. – smartins Dec 04 '08 at 10:59
6

No. You'll have to compile two versions: 64-bit and 32-bit.

Jeff Hubbard
  • 9,444
  • 3
  • 27
  • 27
6

I just found out this solution, from CodeCentral: http://cc.embarcadero.com/Author/802978

It allows to call any 64 bit library from 32 bit code.

It's a complex solution, running an asm-written 64 bit executable in the background, then communicating with it using memory mapped files and windows GDI messages to launch some 64 bit functions from a 32 bit Delphi process.

There is a sample which is able to load any 64 bit library, then call any function of this library, from a 32 bit executable.

Seems to work well. In all cases, code is worth looking at it: it's technical, but well designed!

Arnaud Bouchez
  • 40,947
  • 3
  • 66
  • 152
  • Are you sure you can call *any* 64 bit library from 32 bit code? A 64 bit library could return data which may be inaccesible from a 32 bit process. –  May 27 '11 at 09:59
  • This "bridge" handles a lot of data types: 64 bit, SIMD XMM and YMM registers, x87 and even AVX registers. Memory buffers will be handled via the memory mapped file. The data is returned to 32 bit just as it was received from the 64 bit library. So you may have to call later the 64 bit version of the API if you want to play with an handle retrieved from 64 bit. Since you can write your own 64 bit function (if you know a bit of asm), you can do whatever you want with this library, if the default bridge is not enough for you. If you know what your're doing, you can call *any* 64 bit library. – Arnaud Bouchez May 27 '11 at 13:04
  • For more complex handling, you may write some wrapper using the 64 bit version of FreePascal, then call this FPC library with this bridge from you main Delphi 32 bit application. – Arnaud Bouchez May 27 '11 at 13:05
  • Guess the problem may arise if the 64 bit library returns pointers to memory beyond the 32 bit range - the code will need to copy them back and forth, requiring a wrapper to understand what would need to be mapped and what not, and hoping that buffer is "static" and does not change. If you can control what the library on the 64 bit side does you can achieve it, but calling *any* library looks a bit dangerous to me, the kind of hack I would not use in production code unless I have a very good reason to be forced to work that way. –  May 27 '11 at 14:45
  • @ldsandon If you take a look at this bridge, you'll see that it is able to manage pointers content back and forth, by copying the memory buffers content to the memory mapped file. It will be slower than direct call, of course, but will work. For calling *any* library.... of course it will be difficult, therefore dangerous. This trick was not made to replace all API calls from a Delphi 32 bit exe, but to make just some calls via a native 64 bit wrapper to the API or an external custom libray. – Arnaud Bouchez May 28 '11 at 18:10
  • How can it copy a buffer which it doesn't know the size? Or is it able to tell which parameters holds the buffer size, maybe within a structure? I am not saying *it doesn't work*, I am just saying it's the kind of hack I would be very careful to use in production code. –  May 30 '11 at 12:29
  • @ldsandon Yes, this is definitively a hack. Tricky, but powerful. And from the performance POV, such a solution make sense, since memory mapped structures are perfect for IPC. – Arnaud Bouchez Aug 01 '11 at 13:30
2

No, but you might be able to get around that using COM. If you run the dll inside a COM object which is running as a stand-alone process, and communicate with marshallable interfaces (eg: automation-compatible interfaces), it should work. It's not always feasible, depending on what the dll does and how extensive the integration and call surfaces are, but it is an option which should be able to make that scenario possible.

Nick
  • 6,742
  • 1
  • 20
  • 34
  • Only if it is an out of process COM Service, like an EXE, DCOM or COM+. Otherwise the COM dll would be loaded into your process and has to have been build for the same platform. – Lars Truijens Dec 04 '08 at 09:55