Recent

Author Topic: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?  (Read 4059 times)

korba812

  • Sr. Member
  • ****
  • Posts: 391
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #15 on: March 30, 2023, 12:47:53 pm »
I use software protection dongles originally from Rainbow Sentinel.
There is an SDK to interface with the driver they provide, and it works in Delphi7.
But when I try to port even the simplest application from D7 to Fpc it won't build because the SDK provides an obj file that implements all the API calls into the driver and the obj file generates an error when linking...

I have even gotten an updated SDK from the company with a new obj file, but that too fails. The syntax check completes successfully but when I compile I get the linker error where Fpc does not get to grips with the obj file.

There are 2 different obj files depending on the type of Delphi compiler, one for 32 bit (like Delphi7) and one for 64 bit Delphi.
I stopped using Delphi before it went 64 bit so I cannot check it.
Try converting the .obj (COFF) file to .o (ELF) with objconv:
https://www.agner.org/optimize/#objconv
I've never tried this tool, but maybe you'll get lucky.

BosseB

  • Sr. Member
  • ****
  • Posts: 468
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #16 on: March 30, 2023, 01:33:57 pm »
What about SimpleIPC?
https://wiki.freepascal.org/SimpleIPC
https://github.com/z505/SimpleIPC-lib

On Github there is a demo for Lazarus, and a separate demo for Delphi.
No mention of 32 vs 64-Bit though

It seems like it is a good way not to re-invent the wheel...

The issue I have but it can be tested I guess:
If I use this system for IPC, will it be able to communicate between 32 bit and 64 bit applications on Windows?
My only working comm case to the protection device is to use 32 bit Delphi7 as the server but my clients will obviously all be 64 bit since they are built with present day tools (normally Lazarus/Fpc).

Can a pipe or whatever it is called that it uses traverse the 32/64 bit border on Windows?

Well,
I tried to look at the Github link to get hold of any useful files but after going back and forth I get nowhere...
I simply do not understand how I could use any of this since there seems to be a dll file involved in all examples and nowhere any download or such for that dll file...
I cannot make anything out of the examples, something is clearly missing here.
--
Bo Berglund
Sweden

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #17 on: March 30, 2023, 01:57:55 pm »
IPC is not a standard, just to mention it and not that you are confused and insist to use just one method.

Interprocess Communications can be many things
- WM_COPYDATA, IMHO limited to one kind of bitness
- Clipboard, same as WM_COPYDATA but independent of bitness, downer: it may get killed by users clipboard usage
- DDE (Dynamic Data Exchange), very oldschool, not that efficiant
- File Mapping, I did show, very stable and fast, works on whatever bitness
- MailSlots, another old technology, same as DDE for me
- Pipes, can be anonymous or named pipes, should also always work
- RPC, works accurate but needs to setup a DCE (on windows/Distributed Computing Environment) plus: works independent of Operating System
- Sockets, can work great, also in a I/O way, network needs to be configured to work smooth with it

I might have forgot to mention more but those are in my mind.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

BosseB

  • Sr. Member
  • ****
  • Posts: 468
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #18 on: March 30, 2023, 02:24:22 pm »
Well,
I tried to look at the Github link to get hold of any useful files but after going back and forth I get nowhere...
I simply do not understand how I could use any of this since there seems to be a dll file involved in all examples and nowhere any download or such for that dll file...
I cannot make anything out of the examples, something is clearly missing here.

Back again...
It seems like an important thing to mention to a user is that simpleipc is a unit that is part of Fpc itself!

I was looking for a download of it for example on the Github link but found none...

Here it is on my installation:
C:\Programs\Lazarus_2.2.4\fpc\3.2.2\source\packages\fcl-process\src\simpleipc.pp

So it is now probably a matter of looking at how it has been used in some examples.
I want to be able to send a message consisting of an action verb and some argument and expect a return string with some structured content.
So the server needs to be able to do this in Delphi7 (my first check) because there I have the connection working towards the protection dongle.
So I need to copy the file over to delphi if that is possible.
Or else as shown in the github link make a dll that can be used by Delphi7 to use as a server. THat dll needs to be a 32 bit Windows dll otherwise it cannot be used in Delphi7 program.

The client application that will call the server is a port to FreePascal of a Delphi program so it is 64 bit compiled.

--
Bo Berglund
Sweden

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #19 on: March 30, 2023, 03:25:03 pm »
Well,
I tried to look at the Github link to get hold of any useful files but after going back and forth I get nowhere...
I simply do not understand how I could use any of this since there seems to be a dll file involved in all examples and nowhere any download or such for that dll file...
I cannot make anything out of the examples, something is clearly missing here.
Look inside this file: https://github.com/z505/SimpleIPC-lib/blob/master/dynsimpleipc.lpr
It's a Library!
If you open this project, and compile it you get the mentioned dll/so!!

And in this folder: https://github.com/z505/SimpleIPC-lib/tree/master/demo-lazarus
the second file is the mentioned dll, though probably compiled with Lazarus.
and in the delphi-folder https://github.com/z505/SimpleIPC-lib/tree/master/demo-delphi-console/Win32/Debug
there is only one file....have a guess which one...
« Last Edit: March 30, 2023, 03:28:54 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

BosseB

  • Sr. Member
  • ****
  • Posts: 468
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #20 on: March 30, 2023, 05:21:39 pm »
Thanks for explaining!
Now I did this:
+ Retrieved the GitHub content using the green "Code" button and selected to get a zipfile.
+ After expansion I opened the dynsimpleipc project in my Lazarus 2.2.4 on Windows10 x64
+ Now tested the Run/QuickCompile command but it ends in an error.
+ Then tested the Run/Compile command and it finishes green!
+ Going back to the Run/QuickCompile command it finishes green!
+ Finally tested Run/Build but that again ends in an error that will not go away:

Code: Pascal  [Select][+][-]
  1. Compile Project, Target: demo-lazarus\x86_64-win64\dynsimpleipc.dll: Exit code 1, Errors: 1, Hints: 1
  2. ipcparsemsg.pas(41,25) Hint: Parameter "s" not used
  3. Error: Compilation raised exception internally

I have then changed the Project_Options/Paths/Target file name to these:
Code: Pascal  [Select][+][-]
  1. demo-lazarus\$(TargetCPU)-$(TargetOS)\dynsimpleipc32
  2. and
  3. demo-lazarus\$(TargetCPU)-$(TargetOS)\dynsimpleipc64
  4.  
for the two targets in order to build both a 64 bit and a 32 bit version of the dll.
The 64 is when I set Target to Win64 and 32 when I use Target Win32

There seems to be some kind of interaction between the Build/Compile/QuickCompile commands and however I sequence these one of them always produces this error.

Wonder why it happens?

But anyway the dll files are created both of them.

Next is to provide my existing Delphi7 test application with a server implemented using the dll just built.
« Last Edit: March 30, 2023, 05:23:43 pm by BosseB »
--
Bo Berglund
Sweden

BosseB

  • Sr. Member
  • ****
  • Posts: 468
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #21 on: March 30, 2023, 09:05:25 pm »
So I have now used Lazarus 2.2.4/Fpc 3.2.2 to compile the demolazarus samples.
I have named the dll dynsimpleipc64.dll and changed the name in the dynsimpleipcwrap.pas file accordingly.
I have compiled the ipcserver.exe and ipcclient.exe apps with no errors shown.

At this point I can start the client but not the server, the server shows a nondescript error 0xc000007b.
(See attached screenshot)
I have tried to set a break-point on the first line in the ipcserver.lpr file (which I assume is where the application starts running) but it does not stop there when I start it inside the Lazarus IDE, just shows what is shown in the screenshot.

The only modifications I have done is to name the output dll file with 64 added after the original name.

OTOH the client starts up just fine, but when I test the button to send a string an error is shown (see attached screenshot)

I can understand the client error because it does find that there is no server running...
Since both applications presumably use the same dll the client response indicates to me that the dll is actually working.
So how can I find the cause of this server error???

EDIT:
For some reason only one screenshot made it into my posting (the last one I added), somethiong is not working OK on this forum...
« Last Edit: March 30, 2023, 09:06:58 pm by BosseB »
--
Bo Berglund
Sweden

BosseB

  • Sr. Member
  • ****
  • Posts: 468
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #22 on: March 30, 2023, 09:08:21 pm »
Adding the first screenshot here...
--
Bo Berglund
Sweden

BosseB

  • Sr. Member
  • ****
  • Posts: 468
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #23 on: March 30, 2023, 09:15:40 pm »
And finally added a dummy variable I could inc() in FormCreate so I could set a breakpoint there.
The result when starting from within Lazarus (green arrow) is shown here...
Not stopping at the breakpoint..
« Last Edit: March 30, 2023, 10:31:10 pm by BosseB »
--
Bo Berglund
Sweden

BosseB

  • Sr. Member
  • ****
  • Posts: 468
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #24 on: March 31, 2023, 05:10:10 pm »
Any idea why the demo project from github cannot be used?
I have tried so many different tests now and it comes down to the same thing, the server application can be compiled successfully but not built, which is weird to me.
Further after it has been compiled and I start it by doubleclicking the exe file in Windows Explorer it immediately exits with the error code shown above!

Today I reverted the project for creating the dll to the original so it creates a dll named without the 32 or 64 at the end of the name.
With this dll in place and by building the server after modifying the dll reference name in unit dynsimpleipcwrap as follows:
Code: Pascal  [Select][+][-]
  1. const dll = 'dynsimpleipc.dll';
I compiled a new server executable.

Same-same! It again immediately errors out with the same code as shown before ($C000007B).

It seems like this is also a showstopper for me. :(

Notice that the client application using the same dll does not have this problem, it just exits because it cannot find any server to communicate with when I hit the button...
But before that it shows up so I am able to interact with it.
The server app just dies....

What is REALLY the problem here?
I am on a Windows 10 x64 HP high-end laptop and use Lazarus 2.2.4 with FPC 3.2.2.
--
Bo Berglund
Sweden

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #25 on: March 31, 2023, 05:41:34 pm »
There is an SDK to interface with the driver they provide, and it works in Delphi7.
But when I try to port even the simplest application from D7 to Fpc it won't build because the SDK provides an obj file that implements all the API calls into the driver and the obj file generates an error when linking...

It is unusual for an SDK to provide only obj files, since those tend to be compiler-specific.  Most SDKs provide DLLs so that they can be used different compilers.

That being said, since the objs are usable in your Delphi, I would suggest creating your own DLL in Delphi that uses the objs internally, and then use that DLL in FreePascal.

I noticed that both of the sample applications were GUI style apps, is that a requirement for them to work?
I mean do they utilize the Windows message handler that requires a window to talk to?

The server in this case should not be visible (the Delphi7 app) while the client does have a visible form.

You don't need a visual Form in order to use a window.  A window can be hidden, for instance like TApplication's window, or Delphi's AllocationHWnd() function.

WM_COPYDATA
I dont think that sharing data between 32 and 64 bit works due different LPARAM sizes... but havent tested.

There is no problem with that.  WM_COPYDATA's data gets marshaled across process boundaries, and LPARAM handling is local to each process, so a 32bit process can freely send data to a 64bit process and vice versa.  When sending, WM_COPYDATA takes in an LPARAM pointing to memory which is local to the sender, then the data gets marshaled to the other process, and the receiver gets an LPARAM pointing to memory which is local to the receiver.  So LPARAM being different sizes is not a factor at all.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #26 on: March 31, 2023, 06:55:27 pm »
WM_COPYDATA
I dont think that sharing data between 32 and 64 bit works due different LPARAM sizes... but havent tested.

There is no problem with that.  WM_COPYDATA's data gets marshaled across process boundaries, and LPARAM handling is local to each process, so a 32bit process can freely send data to a 64bit process and vice versa.  When sending, WM_COPYDATA takes in an LPARAM pointing to memory which is local to the sender, then the data gets marshaled to the other process, and the receiver gets an LPARAM pointing to memory which is local to the receiver.  So LPARAM being different sizes is not a factor at all.
Thank you for that information, what I right now can confirm is that I am able to send from 64bit to 32bit but not from 32bit to 64bit.
(32bit built with Delphi, 64bit built with FreePascal/Lazarus)
I hope you have a little time to download my attachment and take a look on to help me figure out what I am doing wrong.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #27 on: March 31, 2023, 07:25:16 pm »
Thank you for that information, what I right now can confirm is that I am able to send from 64bit to 32bit but not from 32bit to 64bit.
(32bit built with Delphi, 64bit built with FreePascal/Lazarus)
I hope you have a little time to download my attachment and take a look on to help me figure out what I am doing wrong.

You are not reporting if FindWindow() fails to locate the window, or even which window it does find.  I would suggest having each app display its Self.Handle in its respective UI, as well as which HWND is being sent to, so you can make sure that FindWindow() is returning the HWND you are expecting.

Or, maybe just get rid of FindWindow() altogether and let the user (ie, you) type in the target HWND directly, ie as a TEdit text that gets converted to an HWND.

Also, you are not checking the return value of SendMessage() for failure at all, either.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #28 on: March 31, 2023, 08:03:55 pm »
Now I do print more it results to find target is okay but nothing happen on 64bit.
Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.btnSendClick(Sender: TObject);
  2. var
  3.   h: THandle;
  4.   cd: TCopyDataStruct;
  5.   rec: TRecToPass;
  6.   res: LRESULT;
  7.   err: DWORD;
  8. begin
  9.   Memo1.Lines.Add('');
  10.   Memo1.Lines.Add('Application Handle: ' + IntToStr(Application.Handle));
  11.   Memo1.Lines.Add('Window Handle: ' + IntToStr(Self.Handle));
  12.   Memo1.Lines.Add('');
  13.   h := FindWindow(nil, 'Demo64');
  14.   if ((h = 0) or (h = INVALID_HANDLE_VALUE)) then
  15.     Exit;
  16.   Memo1.Lines.Add('Found Handle: ' + IntToStr(h));
  17.   Memo1.Lines.Add('');
  18.   rec.s := Self.Edit1.Text;
  19.   rec.i := Random(High(DWORD));
  20.   Self.Label2.Caption := IntToStr(rec.i);
  21.   cd.cbData := SizeOf(rec);
  22.   cd.dwData := rec.i;
  23.   cd.lpData := @rec;
  24.   res := SendMessage(h, WM_COPYDATA, WPARAM(Self.Handle), LPARAM(@cd));
  25.   err := GetLastError;
  26.   Memo1.Lines.Add('Res: ' + IntToStr(Res));
  27.   Memo1.Lines.Add('GetLastError: ' + IntToStr(err));
  28. end;
But maybe I do misunderstand something so I ask for help  :-*
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

BosseB

  • Sr. Member
  • ****
  • Posts: 468
Re: InterProcessCommunication to a Delphi7 app from 64 bit Windows app?
« Reply #29 on: March 31, 2023, 09:50:19 pm »
It is unusual for an SDK to provide only obj files, since those tend to be compiler-specific.  Most SDKs provide DLLs so that they can be used different compilers.

That being said, since the objs are usable in your Delphi, I would suggest creating your own DLL in Delphi that uses the objs internally, and then use that DLL in FreePascal.
Hi Remy, long time no see!
I have retired from my day work now and only have older versions of Delphi available for moonlighting...
So I have switched altogether to Lazarus/Fpc for my hobby projects.

I thought about dll earlier but then realized that Delphi7 or Delphi2007 (which I still have on my PC) are 32 bit Delphi's and so generate a 32 bit dll, which cannot be loaded by a 64 bit application made by FreePascal...

That is why I asked here and was steered into IPC by a response further up.
But I have not had any luck with the GitHub project, I cannot compile the lazarus-demo fully (server app won't start) and the delphi-demo is done for a more recent delphi than what I have.

It would be possible to use TCP/IP sockets through Indy (available on all my platforms) instead but it seems like doing networking for two apps on the same machine to talk to each other is overkill...
--
Bo Berglund
Sweden

 

TinyPortal © 2005-2018