Lazarus

Installation => Windows (32/64) => Topic started by: poiuyt555 on June 25, 2013, 05:15:40 am

Title: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: poiuyt555 on June 25, 2013, 05:15:40 am
Hi.
I have some project and i want to compile it on 64-bit Lazarus.
I use official releases:
lazarus-1.0.10-fpc-2.6.2-win32.exe
lazarus-1.0.10-fpc-2.6.2-win64.exe
Is any difference, problems of porting 32-bit app to 64-bit?

I ask it because i have some problems, some functions not working properly in 64-bit Lazarus. (soon i post here the description of problems). Now i ask in general case.
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: User137 on June 25, 2013, 11:59:38 am
In the documentation
http://wiki.freepascal.org/Code_Conversion_Guide#32bit_.2F_64_bit_support
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: poiuyt555 on June 25, 2013, 12:25:38 pm
Thanks, user137.
I will see your link, and now i post here the first problem:
Windows 7 64-bit.
lazarus-1.0.10-fpc-2.6.2-win32.exe
lazarus-1.0.10-fpc-2.6.2-win64.exe

Problem #1:
This code compiles without errors in 32-bit LAzarus, but didn't compiles in 64-bit:
Code: [Select]
uses
...windows...
...
var
  Form1: TForm1;
  OldWProc   : WNDPROC = nil;
...
function MyWndProc(hWnd: HWND; uiMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
   //
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  OldWProc  := Windows.WNDPROC(SetWindowLong(Handle, GWL_WNDPROC, Integer(@MyWndProc)));
end;

On line  OldWProc  := ... in 64-bit Lazarus it gave me an error:
Error: Illegal type conversion: "LongInt" to "<procedure variable type of function(QWord,LongWord,Int64,Int64):Int64;StdCall>"

How to fix it?
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: User137 on June 25, 2013, 12:56:34 pm
@MyWndProc returns a 64-bit address (when compiled with 64-bit compiler). Even if you did convert it into 32-bit integer first, you would lose information. This truncated address would not be useful for the receiving end.

I mean, PtrInt(@MyWndProc) might compile, but not work as you wanted.
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: taazz on June 25, 2013, 01:01:13 pm
Quote
Ptrint is a signed integer type which has always the same size as a pointer.

Reference : http://www.freepascal.org/docs-html/rtl/system/ptrint.html (http://www.freepascal.org/docs-html/rtl/system/ptrint.html)
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: Leledumbo on June 25, 2013, 01:11:48 pm
And SetWindowLong expects LONG type as the last argument, so casting to Integer is not really valid. Since you target Windows only, LONG is also available (perhaps along with TLONG) so you can directly use that instead.
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: poiuyt555 on June 26, 2013, 04:58:15 am
Thanks to all!

When i replace integer() to PtrInt() - the same error:
OldWProc  := Windows.WNDPROC(SetWindowLong(Handle, GWL_WNDPROC,  PtrInt(@MyWndProc)));
Error: Illegal type conversion: "LongInt" to "<procedure variable type of function(QWord,LongWord,Int64,Int64):Int64;StdCall>"

When i replace SetWindowLong to SetWindowLongPtr it compiles:
OldWProc  := Windows.WNDPROC(SetWindowLongPtr(Handle, GWL_WNDPROC,  PtrInt(@MyWndProc)));

Q1: Is it correct way to solve this problem?
Q2: Is it backward compatibly with 32-bit compiler?
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: poiuyt555 on June 27, 2013, 05:58:53 am
Question # 2:
Why FindAllFiles('c:\') compiled with 64-bit compiler (c - system drive) gives about +1500 files more than compiled with 32-bit compiler on my Win7-64bit.
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: JuhaManninen on June 27, 2013, 08:17:01 am
Use the cross-platform functions provided by FPC libs and LCL, instead of WinAPI. They work for 32- and 64-bits without tweaking.
I don't know why many people still want to use the ancient WinAPI while there is a better cross-platform solution. Maybe WinAPI should be deprecated somehow.
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: Timewarp on June 27, 2013, 10:02:16 am
Quote
Q1: Is it correct way to solve this problem?
Q2: Is it backward compatibly with 32-bit compiler?
That works fine both 32/64.

I've had only few problems while testing 64bit. Using registry did not work properly, and had to make changes. If there is need to disable fpu exceptions, set8087CW($133F); does not help in 64, SetExceptionMask from "math" is needed.

Quote
I don't know why many people still want to use the ancient WinAPI
for example Application.OnMessage is missing from Lazarus. This has actually been biggest problem converting Delphi applications. I have solved it using winapi, there is no other way.
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: JuhaManninen on June 27, 2013, 03:05:15 pm
for example Application.OnMessage is missing from Lazarus. This has actually been biggest problem converting Delphi applications. I have solved it using winapi, there is no other way.

There is no cross-platform solution for Application.OnMessage, it is too Windows specific.
What do you want to do in that event? The same thing can always be implemented differently, although it may require rewriting and refactoring somewhat.
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: Timewarp on June 27, 2013, 04:29:47 pm
The same thing can always be implemented differently
I need all kind of mouse / keyboard / window messages.

For example following simple Delphi code is quite impossible. It captures (and eats) all right mouse clicks. No matter what component is under mouse.
Code: [Select]
private
  procedure MsgHandler(var Msg: TMsg; var Handled: Boolean);

procedure TForm1.MsgHandler(var Msg: TMsg; var Handled: Boolean);
var M: TPoint;
begin
  if Msg.message=WM_RBUTTONDOWN then
  begin
    GetCursorPos(M);
    label1.caption:='Right mouse click '+inttostr(M.X)+' '+inttostr(M.Y);
    handled:=true; //"Eat" this message
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  application.OnMessage:=MsgHandler;
end;
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: poiuyt555 on June 28, 2013, 05:22:03 am
Thanks JuhaManninen, Timewarp.
Quote
Use the cross-platform functions provided by FPC libs and LCL, instead of WinAPI.
But FindAllFiles - this is the Lazarus modern functionality, as i understand.
FindAllFiles is located in FileUtil unit, and is using TFileSearcher.Search method to find for files, which is using FindFirstUTF8/FindNextUTF8, which is using probably, yes, winAPI.
Ex. one of those files which was is not found by 32-bit compiled program:
C:\Windows\system32\7B296FB0-376B-497e-B012-9C450E1B7327-5P-0.C7483456-A289-439d-8115-601632D005A0 

How can you explain this results?
What is it, from where this files?
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: Cyrax on June 28, 2013, 08:09:51 am
All Windows 64-bit versions redirect certain system folders and system registry entries when 32-bit program tries to access them. Only 64-bit program sees these entries fully.

See http://en.wikipedia.org/wiki/WoW64 for more info.
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: poiuyt555 on June 28, 2013, 08:54:29 am
Thanks, Cyrax.
I guess that I understood.

Problem #3:
this code gives me different results on 32 or 64 bit compiler:
Code: [Select]
var tr:  string;
begin
     SetLength(tr, MAX_PATH);
     if not SHGetSpecialFolderPath(0, PChar(tr),CSIDL_PROGRAM_FILES, true) then tr := '';
     result :=PChar(tr);
end;

Compiled with 32-bit compiler:
- when windows is 32-bit          - it returns c:\program files
- when windows is win7 64-bit - it returns c:\program files (x86)
And this is correct for me, but

Compiled with 64-bit compiler:
- when windows is win7 64-bit - it returns c:\program files but not c:\program files (x86)

And if i use flag CSIDL_PROGRAM_FILESX86 - it return correct c:\program files (x86)
But in that case it will be not backward compatibly with 32-bit mode.

Why it is so?
How to fix it?
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: Cyrax on June 28, 2013, 09:04:36 am
It's by design. Under 64-bit Windows 64-bit programs goes under "Program Files" and 32-bit ones under "Program Files (x86)". Why do you need it to be compatible, anyway?
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: Cyrax on June 28, 2013, 10:19:30 am
It seems to me already to be 'plug and play' unless you have some specific code that requires to do unique stuff. 64-bit programs does 64-bit stuff (can't call 32-bit stuff and vice versa) and 32-bit does 32-bit stuff.
Title: Re: Is any difference, problems of porting 32-bit app to 64-bit?
Post by: JuhaManninen on June 29, 2013, 02:18:14 pm
I need all kind of mouse / keyboard / window messages.
For example following simple Delphi code is quite impossible. It captures (and eats) all right mouse clicks. No matter what component is under mouse.
[...]

True, it is not currently possible.
TOnUserInputEvent in Application lets you see and react to all mouse events. Unfortunately it does not let you "eat" or filter out the events.

Code: [Select]
procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.AddOnUserInputHandler(@UserInputHandler);
end;

procedure TForm1.UserInputHandler(Sender: TObject; Msg: Cardinal);
begin
  ...
end;

There are other Application.AddOn... methods for other events, too.

It should be possible to extend OnUserInputEvent + handler to take a var param which you can change.
If you want to dive into LCL events and create a patch for such feature, I think it can be applied.
How much work or side-effects it causes, I have no idea.
TinyPortal © 2005-2018