Did this article resolve your question/issue?



Moving to 64 bits: DLLs and OCXs

« Go Back


TitleMoving to 64 bits: DLLs and OCXs
URL Name000044291
Article Number000166653
EnvironmentProduct: OpenEdge
Version: All supported versions
OS: Windows
Question/Problem Description
Moving to 64 bits: DLLs and OCXs

Issues related to DLLs and ActiveX (OCX) controls that arise when moving an application to the 64-bit GUI client.
Steps to Reproduce
Clarifying Information
Error Message
Defect/Enhancement Number
While 64-bit Windows can run 32-bit Applications, a 32-bit process cannot load a 64-bit DLL and a 64-bit process cannot load a 32-bit DLL.

It is possible for a 16-bit application to call a 32-bit DLL on 32-bit versions of Windows as they can address the same amount of memory because 16-bit and 32-bit applications both run in a 32-bit address space. This is not the case with 32-bit Applications on 64-bit Windows:
  • 32-bit code can only address 4GB of memory, while 64-bit code can address 8TB (terabytes).
  • 32-bit code can't interoperate directly with 64-bit code (or vice versa) because they can't see the same amount of memory.
  • They also have different pointer sizes, which is discussed further below.
To run an ABL Application with the 64-bit client the 32-bit DLLs need to be replaced with their 64-bit equivalents. If the source code for the 32-bit DLLs are available they may be able to be ported to 64-bits. If these are third-party DLLs, ask the vendor whether they have a 64-bit version.
The same applies to ActiveX (OCX) controls. OCX controls are little more than DLLs with a different extension. A 32-bit OCX control cannot be used in a 64-bit Application. Few OCX controls are available in 64-bit versions. If the application makes heavy use of OCX controls these may be the biggest barrier to moving it to the 64-bit GUI client.
Assuming 64-bit versions of the DLLs used by the application can be provided, external procedure definitions need to be reviewed.

If pointer values are passed to an external procedure, those pointers become 64 bits wide in the 64-bit Client. It's common to pass a pointer using a parameter of type LONG:
  • This will not work for a 64-bit pointer. A 64-bit type, INT64 needs to be used. MEMPTR parameters handle this automatically, adjusting to the correct pointer width for the client executable.
  • Passing a pointer in a LONG parameter will work as long as the value of the pointer doesn't exceed 2147483647 (0x000000007FFFFFFF). That is, if the pointer's value can be held in a signed 32-bit value it will work. If a pointer value is passed that is too large for a LONG this will fail with errors like: "Value 2147483648 does not fit in long DLL datatype. (13712)".
  • Since it is not always possible to know in advance whether a pointer in the Application will ever exceed a signed 32-bit value, it's best to assume that they will.
A common use of external procedures is to call the Windows Win32 API.
  • Many Win32 API calls will work without modification because Microsoft didn't change the names of the system DLLs (kernel32.dll, user32.dll, etc.) on 64-bit Windows.
  • Microsoft also guarantee that handle types like HWND and HINSTANCE will not use the high 32 bits of the handle value, even though the handles themselves have expanded to 64 bits.
  • While you can continue to safely pass handle types as LONG parameters to and from external procedures. However, it is common to build structures in MEMPTRs to pass to the Win32 API and the sizes of the structure elements are likely to be larger on 64-bit Windows. You'll have to review each structure you're using and you'll probably have to adjust the sizes and offsets of some structure members.
Another difference between external procedures on 32-bit Windows and 64-bit Windows is the calling convention.
  • On 32-bit Windows the correct calling convention (STDCALL, CDECL, or PASCAL) in external procedure declarations need to be used to avoid corrupting the stack.
  • On 64-bit Windows there is only one calling convention, called FASTCALL. 64-bit OpenEdge ignores any calling convention specified in an external procedure declaration.
Last Modified Date2/27/2020 7:44 AM
Disclaimer The origins of the information on this site may be internal or external to Progress Software Corporation (“Progress”). Progress Software Corporation makes all reasonable efforts to verify this information. However, the information provided is for your information only. Progress Software Corporation makes no explicit or implied claims to the validity of this information.

Any sample code provided on this site is not supported under any Progress support program or service. The sample code is provided on an "AS IS" basis. Progress makes no warranties, express or implied, and disclaims all implied warranties including, without limitation, the implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample code is borne by the user. In no event shall Progress, its employees, or anyone else involved in the creation, production, or delivery of the code be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample code, even if Progress has been advised of the possibility of such damages.