On Wed, 11 Feb 2009, Szak�ts Viktor wrote:
Hi Viktor,
> I've successfully created xhgtk lib using MinGW,
> but for some reason, the .dll creation you've suggested
> throws thousands of errors similar to this:
> ./libxhgtk.a/TWindow.o:TWindow.c:(.text+0x37): undefined reference to
> `hb_vmExecute'
> Do you have any idea what could be missing?
Windows does not support late binding in share libraries so
you have to add harbour.dll to linked libraru list:
hb-mkslib libxhgtk libxhgtk.a `pkg-config --libs gtk+-2.0 libglade-2.0` \
-lharbour
(if necessary use also -L<path> to specify where harbour.dll is located)
and then create Harbour shared binaries.
The second method is creating wrapper for Harbour API functions used
by XHGTK and link it with xhgtk.dll.
harbour/source/vm/maindllp.c is example of such wrapper which can be
used with PCODE DLLs.
In fact this code should be divided.
We should have one file, let's call it maindll.c which will have only
hb_vmProcessSymbolsEx() and hb_vmExecute() functions. Only this functions
are necessary to linked compiled PCODE when -gc[0-2] is used.
The second files should have also all hb_xvm*() functions used by .prg
code compiled with -gc3.
The third one should have wrappers to extended API (hb_par*(), hb_ret*(),
hb_stor*()) functions and others which are defined as public API and
commonly used. F.e. hb_item*(), hb_array*(), hb_hash*(), etc.
>From this files we should create library, f.e. hbdll which will be used
in such cases (create .DLLs which can be linked with static or shared
Harbour application).
Now you can simply try to add maindllp.o to above hb-mkslib command:
hb-mkslib libxhgtk maindllp.o libxhgtk.a \
`pkg-config --libs gtk+-2.0 libglade-2.0` \
To see how it reduce the list of unresolved references and which functions
are still missing and should be added.
If you look at this wrapper then you will find two things which should
be precisely defined because they stop to work due to modified names:
#define HB_DLL_NAME "harbour.dll"
#if defined( __BORLANDC__ )
# define HB_DLL_NAME2 "harbour-b32.dll"
#elif defined( _MSC_VER )
# define HB_DLL_NAME2 "harbour-vc.dll"
#endif
[...]
if( s_hModule == NULL )
{
s_hModule = GetModuleHandle( HB_DLL_NAME );
#ifdef HB_DLL_NAME2
if( s_hModule == NULL )
s_hModule = GetModuleHandle( HB_DLL_NAME2 );
#endif
if( s_hModule == NULL )
s_hModule = GetModuleHandle( NULL );
}
Now BCC and MSVC builds uses different names for DLLs then the old
ones defined in HB_DLL_NAME2 so this code will not detect it. I do
not know if in Windows it's possible to extract module handle using
wildcards, f.e. "harbour*.dll". It not then we have to define strict
naming rules and update build script and above code keeping the names
synced.
If application is linked with static HVM then
s_hModule = GetModuleHandle( NULL );
returns handle to this module.
pProcAddr = GetProcAddress( s_hModule, szProcName );
if( pProcAddr == NULL && szProcName[ 0 ] == '_' )
pProcAddr = GetProcAddress( s_hModule, szProcName + 1 );
extracts function addresses. To make it working also for static HVM
Harbour has to be compiled with exported public symbols (-DHB_DYNLIB)
In this code we already have hack for underscore prefix used by some
C compilers.
/* a little bit off-topic subject */
There is also small problem with functions using variable number of
parameters like: hb_parc( int iParam, ... ) which is also related to
other problem much more serious.
Personally I do not like this ... extended API feature because it breaks
code we all often used expecting default values for wrong types, f.e.:
iVal = hb_parni( 1 ); /* default to 0 */
If used pass array as 1-st parameter then hb_parni() tries to used
unexisting 2-nd parameter as index to this array. On x86 machines it's
usually access to uninitialized memory used as array index so integer
value is extracted from the random item in passed array or 0 when it's
out of bound. When different ABI (calling convention) is used then it
may caused other unpredictable results. F.e. if hardware supports
stack frame protection then it may even cause SIGSEG or sth like that.
I would like to remove ... from all existing extended API functions
and add second set which can be used for Clipper compatibility to
replace _par*() and _stor*() functions, f.e.:
int hb_parni( int iParam );
long hb_parnl( int iParam );
[...]
int hb_vparni( int iParam, ... );
long hb_vparnl( int iParam, ... );
[...]
int hb_storni( int iValue, int iParam );
int hb_stornl( long lValue, int iParam );
[...]
int hb_vstorni( int iValue, int iParam, ... );
int hb_vstornl( long lValue, int iParam, ... );
Such modification resolves the problem, still allows to use hb_v*()
functions in few places where it's usable and additional parameter
with array index is passed.
This is not directly related to .DLL problem but it's occasion to
refresh it and maybe implement soon.
best regards,
Przemek
_______________________________________________
Harbour mailing list
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour