Frank Heckenbach wrote:
Relying on the default linker names was never reliable.
OK, but how to solve the following problem, without relying on linker names:
- create a Mac OS X dynamic library (dylib) - for that purpose, use a GPC unit "MyDylib" - pass -init _MyDylibInit to ld so that MyDylibInit is called when the dynamic library is loaded - declare a procedure MyDylibInit with attribute( name = 'MyDylibInit')
So far no problem, but MyDylibInit ...
- first calls GPCRuntimeInitialize (or GPC_Initialize if you like) declared with external name '_p_initialize' (relying on a linker name that may change) - then calls MyDylibUnitInit, the compiler glue that initializes the MyDylib unit. The external name used to be init_Mydylib but has recently changed to _p__M7_Mydylib_init (relying on a linker name again).
Regards,
Adriaan van Os
Adriaan van Os wrote:
Frank Heckenbach wrote:
Relying on the default linker names was never reliable.
OK, but how to solve the following problem, without relying on linker names:
- create a Mac OS X dynamic library (dylib)
- for that purpose, use a GPC unit "MyDylib"
- pass -init _MyDylibInit to ld so that MyDylibInit is called when the
dynamic library is loaded
- declare a procedure MyDylibInit with attribute( name = 'MyDylibInit')
So far no problem, but MyDylibInit ...
- first calls GPCRuntimeInitialize (or GPC_Initialize if you like)
declared with external name '_p_initialize' (relying on a linker name that may change)
Yes, three fixed names, including this one as well as _p_finalize (RTS cleanup) and _p__M0_init (Pascal main program -- not in units, of course), are indeed special. They're "documented" in gpc-in-c.h though this is aimed at C interfaces, not really useful for you. So indeed, I suppose I should add those declarations in gpc.pas, so they can be properly called from Pascal:
{ Initialize the GPC Run Time System. This is normally called automatically. Call it manually only in very special situations. ArgumentCount, Arguments are argc and argv in C; StartEnvironment is the environment variable pointer, and can be nil if other ways to obtain the environment are available. Options can be 0 or a combination of ro_* flags as defined in rts/constants.def. } procedure GPC_Initialize (ArgumentCount: CInteger; Arguments, StartEnvironment: PCStrings; Options: CInteger); attribute (name = '_p_initialize'); external;
{ Finalize the GPC Run Time System. This is normally called automatically. Call it manually only in very special situations. } procedure GPC_Finalize; attribute (name = '_p_finalize'); external;
BTW, those linker names might have to change again. There was recently, in March, a thread about a name conflict of _p_initialize with plotutils. Though it turned out that actually plotutils should change the name, and GPC reserving a `_p_' prefix seems reasonable, if there's still desire by some to change the names, we should now agree on a set of new names and change them once and finally.
- then calls MyDylibUnitInit, the compiler glue that initializes the
MyDylib unit. The external name used to be init_Mydylib but has recently changed to _p__M7_Mydylib_init (relying on a linker name again).
unit MyDylib; attribute (name = 'MyDylib');
procedure MyDylibUnitInit; external name 'MyDylib_init';
This part was recently changed, together with the introduction of QI. Now only the ending part (_init) is "magic", but I hope it won't change again (cf. rts/init.pas which has the same issue).
Frank
Frank Heckenbach wrote:
Adriaan van Os wrote:
- first calls GPCRuntimeInitialize (or GPC_Initialize if you like)
declared with external name '_p_initialize' (relying on a linker name that may change)
Yes, three fixed names, including this one as well as _p_finalize (RTS cleanup) and _p__M0_init (Pascal main program -- not in units, of course), are indeed special. They're "documented" in gpc-in-c.h though this is aimed at C interfaces, not really useful for you. So indeed, I suppose I should add those declarations in gpc.pas, so they can be properly called from Pascal:
{ Initialize the GPC Run Time System. This is normally called automatically. Call it manually only in very special situations. ArgumentCount, Arguments are argc and argv in C; StartEnvironment is the environment variable pointer, and can be nil if other ways to obtain the environment are available. Options can be 0 or a combination of ro_* flags as defined in rts/constants.def. } procedure GPC_Initialize (ArgumentCount: CInteger; Arguments, StartEnvironment: PCStrings; Options: CInteger); attribute (name = '_p_initialize'); external;
{ Finalize the GPC Run Time System. This is normally called automatically. Call it manually only in very special situations. } procedure GPC_Finalize; attribute (name = '_p_finalize'); external;
OK, thanks.
BTW, those linker names might have to change again. There was recently, in March, a thread about a name conflict of _p_initialize with plotutils. Though it turned out that actually plotutils should change the name, and GPC reserving a `_p_' prefix seems reasonable, if there's still desire by some to change the names, we should now agree on a set of new names and change them once and finally.
- then calls MyDylibUnitInit, the compiler glue that initializes the
MyDylib unit. The external name used to be init_Mydylib but has recently changed to _p__M7_Mydylib_init (relying on a linker name again).
unit MyDylib; attribute (name = 'MyDylib');
procedure MyDylibUnitInit; external name 'MyDylib_init';
Ah yes, that works.
Regards,
Adriaan van Os