Win32 GMP Port (notes for VB, Delphi, Pascal, PowerBasic, etc)

White, Jim (ITD) Jim.White@DEFRA.GSI.GOV.UK
Tue, 3 Jun 2003 15:03:43 +0100


I have some useful information for Win32 users who would like to use
deltatrinity's "ready-rolled" Win32 GMP DLL's.

deltatrinity's successful builds of Win32 DLL's are the only known source of
GMP in this format (and he has done very well to do so, judging by
problems/queries reported by others)

They were built using MinGW and deltatrinity has provided DLL versions for
most current PC's (Pentium, P2, P4, x386).

There major pitfall for Win32 users trying to call these DLL's is the use of
the correct calling convention (CDECL vs STDCALL).  This is a common problem
when trying to mix Unix(ANSI C) with Windows.

deltatrinity's current DLL's use the standard Unix/C calling convention
(aka. "cdecl"). Windows API, and most Win32 programming environments (Visual
Basic, Pascal) use the "stdcall" (aka "sdecl", "pascal") calling convention.
(The difference is that Unix expects the CALLER of a routine to clear the
stack, rather than the routine itself. The compiler needs to know whether it
has to generate the cleanup code when making a call to an external
function).

If you are using Visual C, or PowerBasic, then this is no problem, as you
can simply tell the compiler  that external entry points in GMP are to be
called using "cdecl".

But other language environments might not have such an option - Visual Basic
(VB) in particular does NOT, and VB cannot be used to call CDECL-style
DLL's. 

However, this problem is easily resolved by calling the DLL indirectly, via
a "wrapper DLL" which is written in C (or PowerBasic) and simply maps the
calls correctly.

Example:

   PB wrapper DLL:

      TYPE MPF
         mp_prec AS LONG
         mp_size AS LONG
         mp_expt AS LONG
         mp_limb AS LONG
         END TYPE

      DECLARE SUB cMPFinit CDECL LIB "libgmp-3.dll" ALIAS "__gmpf_init" (X
AS MPF)
      DECLARE SUB cMPFclear CDECL LIB "libgmp-3.dll" ALIAS "__gmpf_clear" (X
AS MPF)

      SUB MPFinit(x AS MPF) EXPORT
         CALL cMPFinit(x)
         END SUB

      SUB MPFclear(x AS MPF) EXPORT
         CALL cMPFclear(x)
         END SUB

This DLL exports "MPFINIT" and "MPFCLEAR" which are simply interludes to the
real mpf_init and mpf_free routines in libgmp-3.  But Visual Basic (and
Pascal, and various other languages) can all call GMP via this wrapper dll.

Here's a similar "wrapper dll" approach in C  (example based on "lcc"
compiler):

   extern void __gmpf_init((mpf_ptr));

   void	_stdcall __declspec(dllexport) MPFINIT(x)
      mpf_ptr x;
      {__gmpfinit(x);}


I will make a separate recommendation about a modification to the GMP
configuration that would eliminate these problems and make the DLL's more
prtable for Win32 users.


Regards

Dr Memory