Ilya Zakharevich on Sat, 14 Nov 1998 18:32:26 -0500 (EST)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: DOS + pari-2.0.12.alpha


Bill Daly writes:
> For 32-bit Windows (i.e. conditioned by #ifdef _WIN32), the functions
> you are looking for are the following. These are defined in windows.h,
> which you should include to get the correct prototypes.
> 
> // load the DLL file 'dllfile' and return a handle to it
> HMODULE hdll;	// HMODULE is actually a void*
> hdll = LoadLibrary(dllname);	// dllname can be any char*
> 
> // find the address of the function 'funcname' in the library whose
> handle is 'hdll'
> FARPROC procaddr;	// FARPROC is typedef'ed as int (FAR WINAPI
> *FARPROC)() [see below]
> procaddr = GetProcAddress(hdll, funcname);	// funcname can be any char*
> 
> You will have to typecast the procaddr to something like void*
> (*proc)(), because WINAPI maps to __stdcall, which specifies a calling
> sequence different from cdecl. (In particular, __stdcall functions pop
> their argument lists within the called function, rather than in the
> calling function.)

You are missing the point.  There is no problem to write dl_open()-
and friends emulation on any particular platform.  The problem is that
dynalinking model of PARI is too primitive to accomodate the
difference of *semantic* of dynalinking and the difference of build
processes.

PARI assumes "soft" dynalinking, when the symbols are resolved at run
time, and assumes "data" dynalinking, when data may be exported as
well as code.  I think M$ platforms should be hardest to accomodate,
since they are the only once I know which use hard+nodata model.

AIX, OS/2 (and a handful of others) use hard+data model, and the only
change to accomodate this is a build process.  But to circumvent
absense of data dynaloading means a complete rethinking (or painful
macroization, ask if you are interested) of the code.

Here for your convenience are details of "hard" dynaloading (this is
what happens if you want your symbols to be resolved automatically, of
course the procedure of on-demand load is different):

     a) during *link* stage each symbol is resolved do either map to
	an address inside *this* module (either .exe, or .dll), or to
	an address in some other .dll (which one is decided at link
	stage).

	In particular, a .dll cannot refer to symbols in the
	executable.  Moreover, before linking any module one needs to
	know all the exportable symbols from any other module ("export
	lists").

     b) How to build an expandable "toolkit" in such an atmosphere?
	The solution below needs no code change wrt "soft" model,
	there are other (painful) solutions with code rework which I
	will ignore.

	1) Since the extension needs to be able to link to symbols in
           the core of the toolkit, the core should be in a .dll.

	2) Since the core needs to be able to ask the extension to do
           something, the extension should have at least one symbol
           "initialize" exportable ("fill the following structure which I
           will use to request your service").

	   Alternately, the extension may export all the things one
           may ask it to perform, but this is worse, since the core
           does not know which things it may ask the extension to do.

	3) Hmm, I think there is no "3"...   In GP case the extension
           will add elements to the global table of available commands
           in the "initialize" routine.  To facilitate static linking,
           the actual name of "initialize" routine should include the
           extension name, like "extensionName_load_initialize".

Thus the build process for the core-PARI should facilitate building a
PARI DLL, and a symbol list for this DLL.  THe extension build process
should be able to write an export list with one symbol.  

GP should be able to link with this PARI DLL too (though this is
trivial at least on OS/2, since export lists may be converted to usual
libraries you may link as with a usual library).

Ilya