- change long to intptr_t for 64bit windows compatability

- change vmMain arguments back to int. 64bit types are apparently not
  needed there. Only the syscall function needs them.
This commit is contained in:
Ludwig Nussel 2006-02-18 19:07:23 +00:00
parent e129637b5a
commit 4c242115dc
20 changed files with 71 additions and 56 deletions

14
README
View file

@ -148,10 +148,18 @@ Using Demo Data Files
If you wish to compile external mods as shared libraries on a 64bit platform, If you wish to compile external mods as shared libraries on a 64bit platform,
and the mod source is derived from the id Q3 SDK, you will need to modify the and the mod source is derived from the id Q3 SDK, you will need to modify the
interface code a little. Open the files ending in _syscalls.c and change interface code a little. Open the files ending in _syscalls.c and change
every instance of int to long in the declaration of the syscall function every instance of int to intptr_t in the declaration of the syscall function
pointer and the dllEntry function. Also find the vmMain function for each pointer and the dllEntry function. Also find the vmMain function for each
module (usually in cg_main.c g_main.c etc.) and similarly replace every module (usually in cg_main.c g_main.c etc.) and similarly replace the return
instance of int in the prototype with long. value in the prototype with intptr_t (arg0, arg1, ...stay int).
Add the following code snippet to q_shared.h:
#ifdef Q3_VM
typedef int intptr_t;
#else
#include <stdint.h>
#endif
Note if you simply wish to run mods on a 64bit platform you do not need to Note if you simply wish to run mods on a 64bit platform you do not need to
recompile anything since by default Q3 uses a virtual machine system. recompile anything since by default Q3 uses a virtual machine system.

View file

@ -43,7 +43,7 @@ This is the only way control passes into the module.
This must be the very first function compiled into the .q3vm file This must be the very first function compiled into the .q3vm file
================ ================
*/ */
long vmMain( long command, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long arg8, long arg9, long arg10, long arg11 ) { intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) {
switch ( command ) { switch ( command ) {
case CG_INIT: case CG_INIT:

View file

@ -28,10 +28,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cg_local.h" #include "cg_local.h"
static long (QDECL *syscall)( long arg, ... ) = (long (QDECL *)( long, ...))-1; static intptr_t (QDECL *syscall)( intptr_t arg, ... ) = (intptr_t (QDECL *)( intptr_t, ...))-1;
void dllEntry( long (QDECL *syscallptr)( long arg,... ) ) { void dllEntry( intptr_t (QDECL *syscallptr)( intptr_t arg,... ) ) {
syscall = syscallptr; syscall = syscallptr;
} }

View file

@ -412,7 +412,7 @@ CL_CgameSystemCalls
The cgame module is making a system call The cgame module is making a system call
==================== ====================
*/ */
long CL_CgameSystemCalls( long *args ) { intptr_t CL_CgameSystemCalls( intptr_t *args ) {
switch( args[0] ) { switch( args[0] ) {
case CG_PRINT: case CG_PRINT:
Com_Printf( "%s", VMA(1) ); Com_Printf( "%s", VMA(1) );

View file

@ -764,7 +764,7 @@ CL_UISystemCalls
The ui module is making a system call The ui module is making a system call
==================== ====================
*/ */
long CL_UISystemCalls( long *args ) { intptr_t CL_UISystemCalls( intptr_t *args ) {
switch( args[0] ) { switch( args[0] ) {
case UI_ERROR: case UI_ERROR:
Com_Error( ERR_DROP, "%s", VMA(1) ); Com_Error( ERR_DROP, "%s", VMA(1) );

View file

@ -200,7 +200,7 @@ This is the only way control passes into the module.
This must be the very first function compiled into the .q3vm file This must be the very first function compiled into the .q3vm file
================ ================
*/ */
long vmMain( long command, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long arg8, long arg9, long arg10, long arg11 ) { intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) {
switch ( command ) { switch ( command ) {
case GAME_INIT: case GAME_INIT:
G_InitGame( arg0, arg1, arg2 ); G_InitGame( arg0, arg1, arg2 );
@ -209,7 +209,7 @@ long vmMain( long command, long arg0, long arg1, long arg2, long arg3, long arg4
G_ShutdownGame( arg0 ); G_ShutdownGame( arg0 );
return 0; return 0;
case GAME_CLIENT_CONNECT: case GAME_CLIENT_CONNECT:
return (long)ClientConnect( arg0, arg1, arg2 ); return (intptr_t)ClientConnect( arg0, arg1, arg2 );
case GAME_CLIENT_THINK: case GAME_CLIENT_THINK:
ClientThink( arg0 ); ClientThink( arg0 );
return 0; return 0;

View file

@ -28,10 +28,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#error "Do not use in VM build" #error "Do not use in VM build"
#endif #endif
static long (QDECL *syscall)( long arg, ... ) = (long (QDECL *)( long, ...))-1; static intptr_t (QDECL *syscall)( intptr_t arg, ... ) = (intptr_t (QDECL *)( intptr_t, ...))-1;
void dllEntry( long (QDECL *syscallptr)( long arg,... ) ) { void dllEntry( intptr_t (QDECL *syscallptr)( intptr_t arg,... ) ) {
syscall = syscallptr; syscall = syscallptr;
} }

View file

@ -40,7 +40,7 @@ This is the only way control passes into the module.
This must be the very first function compiled into the .qvm file This must be the very first function compiled into the .qvm file
================ ================
*/ */
long vmMain( long command, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long arg8, long arg9, long arg10, long arg11 ) { intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) {
switch ( command ) { switch ( command ) {
case UI_GETAPIVERSION: case UI_GETAPIVERSION:
return UI_API_VERSION; return UI_API_VERSION;

View file

@ -928,7 +928,7 @@ void *Z_TagMalloc( int size, int tag ) {
// //
size += sizeof(memblock_t); // account for size of block header size += sizeof(memblock_t); // account for size of block header
size += 4; // space for memory trash tester size += 4; // space for memory trash tester
size = PAD(size, sizeof(long)); // align to 32/64 bit boundary size = PAD(size, sizeof(intptr_t)); // align to 32/64 bit boundary
base = rover = zone->rover; base = rover = zone->rover;
start = base->prev; start = base->prev;
@ -1530,7 +1530,7 @@ void Com_InitHunkMemory( void ) {
Com_Error( ERR_FATAL, "Hunk data failed to allocate %i megs", s_hunkTotal / (1024*1024) ); Com_Error( ERR_FATAL, "Hunk data failed to allocate %i megs", s_hunkTotal / (1024*1024) );
} }
// cacheline align // cacheline align
s_hunkData = (byte *) ( ( (long)s_hunkData + 31 ) & ~31 ); s_hunkData = (byte *) ( ( (intptr_t)s_hunkData + 31 ) & ~31 );
Hunk_Clear(); Hunk_Clear();
Cmd_AddCommand( "meminfo", Com_Meminfo_f ); Cmd_AddCommand( "meminfo", Com_Meminfo_f );
@ -1750,7 +1750,7 @@ void *Hunk_AllocateTempMemory( int size ) {
Hunk_SwapBanks(); Hunk_SwapBanks();
size = PAD(size, sizeof(long)) + sizeof( hunkHeader_t ); size = PAD(size, sizeof(intptr_t)) + sizeof( hunkHeader_t );
if ( hunk_temp->temp + hunk_permanent->permanent + size > s_hunkTotal ) { if ( hunk_temp->temp + hunk_permanent->permanent + size > s_hunkTotal ) {
Com_Error( ERR_DROP, "Hunk_AllocateTempMemory: failed on %i", size ); Com_Error( ERR_DROP, "Hunk_AllocateTempMemory: failed on %i", size );

View file

@ -102,6 +102,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//============================================================= //=============================================================
#ifdef Q3_VM
typedef int intptr_t;
#else
#include <inttypes.h>
#endif
typedef unsigned char byte; typedef unsigned char byte;
typedef enum {qfalse, qtrue} qboolean; typedef enum {qfalse, qtrue} qboolean;

View file

@ -317,7 +317,7 @@ typedef enum {
} sharedTraps_t; } sharedTraps_t;
void VM_Init( void ); void VM_Init( void );
vm_t *VM_Create( const char *module, long (*systemCalls)(long *), vm_t *VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *),
vmInterpret_t interpret ); vmInterpret_t interpret );
// module should be bare: "cgame", not "cgame.dll" or "vm/cgame.qvm" // module should be bare: "cgame", not "cgame.dll" or "vm/cgame.qvm"
@ -325,18 +325,18 @@ void VM_Free( vm_t *vm );
void VM_Clear(void); void VM_Clear(void);
vm_t *VM_Restart( vm_t *vm ); vm_t *VM_Restart( vm_t *vm );
long QDECL VM_Call( vm_t *vm, long callNum, ... ); intptr_t QDECL VM_Call( vm_t *vm, int callNum, ... );
void VM_Debug( int level ); void VM_Debug( int level );
void *VM_ArgPtr( long intValue ); void *VM_ArgPtr( intptr_t intValue );
void *VM_ExplicitArgPtr( vm_t *vm, long intValue ); void *VM_ExplicitArgPtr( vm_t *vm, intptr_t intValue );
#define VMA(x) VM_ArgPtr(args[x]) #define VMA(x) VM_ArgPtr(args[x])
static ID_INLINE float _vmf(long x) static ID_INLINE float _vmf(intptr_t x)
{ {
union { union {
long l; intptr_t l;
float f; float f;
} t; } t;
t.l = x; t.l = x;
@ -963,8 +963,8 @@ void Sys_Init (void);
// general development dll loading for virtual machine testing // general development dll loading for virtual machine testing
// fqpath param added 7/20/02 by T.Ray - Sys_LoadDll is only called in vm.c at this time // fqpath param added 7/20/02 by T.Ray - Sys_LoadDll is only called in vm.c at this time
void * QDECL Sys_LoadDll( const char *name, char *fqpath , long (QDECL **entryPoint)(long, ...), void * QDECL Sys_LoadDll( const char *name, char *fqpath , intptr_t (QDECL **entryPoint)(int, ...),
long (QDECL *systemcalls)(long, ...) ); intptr_t (QDECL *systemcalls)(intptr_t, ...) );
void Sys_UnloadDll( void *dllHandle ); void Sys_UnloadDll( void *dllHandle );
void Sys_UnloadGame( void ); void Sys_UnloadGame( void );

View file

@ -329,10 +329,10 @@ Dlls will call this directly
============ ============
*/ */
long QDECL VM_DllSyscall( long arg, ... ) { intptr_t QDECL VM_DllSyscall( intptr_t arg, ... ) {
#if !id386 #if !id386
// rcg010206 - see commentary above // rcg010206 - see commentary above
long args[16]; intptr_t args[16];
int i; int i;
va_list ap; va_list ap;
@ -340,7 +340,7 @@ long QDECL VM_DllSyscall( long arg, ... ) {
va_start(ap, arg); va_start(ap, arg);
for (i = 1; i < sizeof (args) / sizeof (args[i]); i++) for (i = 1; i < sizeof (args) / sizeof (args[i]); i++)
args[i] = va_arg(ap, long); args[i] = va_arg(ap, intptr_t);
va_end(ap); va_end(ap);
return currentVM->systemCall( args ); return currentVM->systemCall( args );
@ -471,7 +471,7 @@ vm_t *VM_Restart( vm_t *vm ) {
// DLL's can't be restarted in place // DLL's can't be restarted in place
if ( vm->dllHandle ) { if ( vm->dllHandle ) {
char name[MAX_QPATH]; char name[MAX_QPATH];
long (*systemCall)( long *parms ); intptr_t (*systemCall)( intptr_t *parms );
systemCall = vm->systemCall; systemCall = vm->systemCall;
Q_strncpyz( name, vm->name, sizeof( name ) ); Q_strncpyz( name, vm->name, sizeof( name ) );
@ -507,7 +507,7 @@ it will attempt to load as a system dll
#define STACK_SIZE 0x20000 #define STACK_SIZE 0x20000
vm_t *VM_Create( const char *module, long (*systemCalls)(long *), vm_t *VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *),
vmInterpret_t interpret ) { vmInterpret_t interpret ) {
vm_t *vm; vm_t *vm;
vmHeader_t *header; vmHeader_t *header;
@ -648,7 +648,7 @@ void VM_Clear(void) {
lastVM = NULL; lastVM = NULL;
} }
void *VM_ArgPtr( long intValue ) { void *VM_ArgPtr( intptr_t intValue ) {
if ( !intValue ) { if ( !intValue ) {
return NULL; return NULL;
} }
@ -664,7 +664,7 @@ void *VM_ArgPtr( long intValue ) {
} }
} }
void *VM_ExplicitArgPtr( vm_t *vm, long intValue ) { void *VM_ExplicitArgPtr( vm_t *vm, intptr_t intValue ) {
if ( !intValue ) { if ( !intValue ) {
return NULL; return NULL;
} }
@ -709,9 +709,9 @@ locals from sp
#define MAX_STACK 256 #define MAX_STACK 256
#define STACK_MASK (MAX_STACK-1) #define STACK_MASK (MAX_STACK-1)
long QDECL VM_Call( vm_t *vm, long callnum, ... ) { intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... ) {
vm_t *oldVM; vm_t *oldVM;
int r; intptr_t r;
int i; int i;
if ( !vm ) { if ( !vm ) {
@ -729,11 +729,11 @@ long QDECL VM_Call( vm_t *vm, long callnum, ... ) {
// if we have a dll loaded, call it directly // if we have a dll loaded, call it directly
if ( vm->entryPoint ) { if ( vm->entryPoint ) {
//rcg010207 - see dissertation at top of VM_DllSyscall() in this file. //rcg010207 - see dissertation at top of VM_DllSyscall() in this file.
long args[10]; int args[10];
va_list ap; va_list ap;
va_start(ap, callnum); va_start(ap, callnum);
for (i = 0; i < sizeof (args) / sizeof (args[i]); i++) { for (i = 0; i < sizeof (args) / sizeof (args[i]); i++) {
args[i] = va_arg(ap, long); args[i] = va_arg(ap, int);
} }
va_end(ap); va_end(ap);
@ -758,7 +758,7 @@ long QDECL VM_Call( vm_t *vm, long callnum, ... ) {
a.callnum = callnum; a.callnum = callnum;
va_start(ap, callnum); va_start(ap, callnum);
for (i = 0; i < sizeof (a.args) / sizeof (a.args[0]); i++) { for (i = 0; i < sizeof (a.args) / sizeof (a.args[0]); i++) {
a.args[i] = va_arg(ap, long); a.args[i] = va_arg(ap, int);
} }
va_end(ap); va_end(ap);
#ifndef NO_VM_COMPILED #ifndef NO_VM_COMPILED
@ -886,6 +886,6 @@ void VM_LogSyscalls( int *args ) {
f = fopen("syscalls.log", "w" ); f = fopen("syscalls.log", "w" );
} }
callnum++; callnum++;
fprintf(f, "%i: %li (%i) = %i %i %i %i\n", callnum, (long)(args - (int *)currentVM->dataBase), fprintf(f, "%i: %"PRIiPTR" (%i) = %i %i %i %i\n", callnum, (intptr_t)(args - (int *)currentVM->dataBase),
args[0], args[1], args[2], args[3], args[4] ); args[0], args[1], args[2], args[3], args[4] );
} }

View file

@ -493,7 +493,7 @@ nextInstruction2:
src = (int *)&image[ r0&dataMask ]; src = (int *)&image[ r0&dataMask ];
dest = (int *)&image[ r1&dataMask ]; dest = (int *)&image[ r1&dataMask ];
if ( ( (long)src | (long)dest | count ) & 3 ) { if ( ( (intptr_t)src | (intptr_t)dest | count ) & 3 ) {
// happens in westernq3 // happens in westernq3
Com_Printf( S_COLOR_YELLOW "Warning: OP_BLOCK_COPY not dword aligned\n"); Com_Printf( S_COLOR_YELLOW "Warning: OP_BLOCK_COPY not dword aligned\n");
} }
@ -534,16 +534,16 @@ nextInstruction2:
//VM_LogSyscalls( (int *)&image[ programStack + 4 ] ); //VM_LogSyscalls( (int *)&image[ programStack + 4 ] );
{ {
long* argptr = (long *)&image[ programStack + 4 ]; intptr_t* argptr = (intptr_t *)&image[ programStack + 4 ];
#if __WORDSIZE == 64 #if __WORDSIZE == 64
// the vm has ints on the stack, we expect // the vm has ints on the stack, we expect
// longs so we have to convert it // longs so we have to convert it
long argarr[16]; intptr_t argarr[16];
int i; int i;
for (i = 0; i < 16; ++i) { for (i = 0; i < 16; ++i) {
argarr[i] = *(int*)&image[ programStack + 4 + 4*i ]; argarr[i] = *(int*)&image[ programStack + 4 + 4*i ];
argptr = argarr;
} }
argptr = argarr;
#endif #endif
r = vm->systemCall( argptr ); r = vm->systemCall( argptr );
} }

View file

@ -127,7 +127,7 @@ struct vm_s {
// DO NOT MOVE OR CHANGE THESE WITHOUT CHANGING THE VM_OFFSET_* DEFINES // DO NOT MOVE OR CHANGE THESE WITHOUT CHANGING THE VM_OFFSET_* DEFINES
// USED BY THE ASM CODE // USED BY THE ASM CODE
int programStack; // the vm may be recursively entered int programStack; // the vm may be recursively entered
long (*systemCall)( long *parms ); intptr_t (*systemCall)( intptr_t *parms );
//------------------------------------ //------------------------------------
@ -135,7 +135,8 @@ struct vm_s {
// for dynamic linked modules // for dynamic linked modules
void *dllHandle; void *dllHandle;
long (QDECL *entryPoint)( long callNum, ... ); intptr_t (QDECL *entryPoint)( int callNum, ... );
void (*destroy)(vm_t* self);
// for interpreted modules // for interpreted modules
qboolean currentlyInterpreting; qboolean currentlyInterpreting;

View file

@ -192,7 +192,7 @@ void callAsmCall(void)
currentVM->programStack = callProgramStack - 4; currentVM->programStack = callProgramStack - 4;
*(int *)((byte *)currentVM->dataBase + callProgramStack + 4) = callSyscallNum; *(int *)((byte *)currentVM->dataBase + callProgramStack + 4) = callSyscallNum;
//VM_LogSyscalls((int *)((byte *)currentVM->dataBase + callProgramStack + 4) ); //VM_LogSyscalls((int *)((byte *)currentVM->dataBase + callProgramStack + 4) );
*(callOpStack2+1) = currentVM->systemCall( (long *)((byte *)currentVM->dataBase + callProgramStack + 4) ); *(callOpStack2+1) = currentVM->systemCall( (intptr_t *)((byte *)currentVM->dataBase + callProgramStack + 4) );
currentVM = savedVM; currentVM = savedVM;
} }

View file

@ -305,7 +305,7 @@ SV_GameSystemCalls
The module is making a system call The module is making a system call
==================== ====================
*/ */
long SV_GameSystemCalls( long *args ) { intptr_t SV_GameSystemCalls( intptr_t *args ) {
switch( args[0] ) { switch( args[0] ) {
case G_PRINT: case G_PRINT:
Com_Printf( "%s", VMA(1) ); Com_Printf( "%s", VMA(1) );

View file

@ -165,7 +165,7 @@ void _UI_KeyEvent( int key, qboolean down );
void _UI_MouseEvent( int dx, int dy ); void _UI_MouseEvent( int dx, int dy );
void _UI_Refresh( int realtime ); void _UI_Refresh( int realtime );
qboolean _UI_IsFullscreen( void ); qboolean _UI_IsFullscreen( void );
long vmMain( long command, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, long arg8, long arg9, long arg10, long arg11 ) { intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) {
switch ( command ) { switch ( command ) {
case UI_GETAPIVERSION: case UI_GETAPIVERSION:
return UI_API_VERSION; return UI_API_VERSION;

View file

@ -28,9 +28,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#error "Do not use in VM build" #error "Do not use in VM build"
#endif #endif
static long (QDECL *syscall)( long arg, ... ) = (long (QDECL *)( long, ...))-1; static intptr_t (QDECL *syscall)( intptr_t arg, ... ) = (intptr_t (QDECL *)( intptr_t, ...))-1;
void dllEntry( long (QDECL *syscallptr)( long arg,... ) ) { void dllEntry( intptr_t (QDECL *syscallptr)( intptr_t arg,... ) ) {
syscall = syscallptr; syscall = syscallptr;
} }

View file

@ -766,11 +766,11 @@ static void* try_dlopen(const char* base, const char* gamedir, const char* fname
} }
void *Sys_LoadDll( const char *name, char *fqpath , void *Sys_LoadDll( const char *name, char *fqpath ,
long (**entryPoint)(long, ...), intptr_t (**entryPoint)(int, ...),
long (*systemcalls)(long, ...) ) intptr_t (*systemcalls)(intptr_t, ...) )
{ {
void *libHandle; void *libHandle;
void (*dllEntry)( long (*syscallptr)(long, ...) ); void (*dllEntry)( intptr_t (*syscallptr)(intptr_t, ...) );
char curpath[MAX_OSPATH]; char curpath[MAX_OSPATH];
char fname[MAX_OSPATH]; char fname[MAX_OSPATH];
char *basepath; char *basepath;

View file

@ -526,10 +526,10 @@ extern char *FS_BuildOSPath( const char *base, const char *game, const char *qp
// fqpath param added 7/20/02 by T.Ray - Sys_LoadDll is only called in vm.c at this time // fqpath param added 7/20/02 by T.Ray - Sys_LoadDll is only called in vm.c at this time
// fqpath will be empty if dll not loaded, otherwise will hold fully qualified path of dll module loaded // fqpath will be empty if dll not loaded, otherwise will hold fully qualified path of dll module loaded
// fqpath buffersize must be at least MAX_QPATH+1 bytes long // fqpath buffersize must be at least MAX_QPATH+1 bytes long
void * QDECL Sys_LoadDll( const char *name, char *fqpath , long (QDECL **entryPoint)(long, ...), void * QDECL Sys_LoadDll( const char *name, char *fqpath , intptr_t (QDECL **entryPoint)(intptr_t, ...),
long (QDECL *systemcalls)(long, ...) ) { intptr_t (QDECL *systemcalls)(intptr_t, ...) ) {
HINSTANCE libHandle; HINSTANCE libHandle;
void (QDECL *dllEntry)( long (QDECL *syscallptr)(long, ...) ); void (QDECL *dllEntry)( intptr_t (QDECL *syscallptr)(intptr_t, ...) );
char *basepath; char *basepath;
char *cdpath; char *cdpath;
char *gamedir; char *gamedir;
@ -606,8 +606,8 @@ void * QDECL Sys_LoadDll( const char *name, char *fqpath , long (QDECL **entryPo
} }
#endif #endif
dllEntry = ( void (QDECL *)(long (QDECL *)( long, ... ) ) )GetProcAddress( libHandle, "dllEntry" ); dllEntry = ( void (QDECL *)(intptr_t (QDECL *)( intptr_t, ... ) ) )GetProcAddress( libHandle, "dllEntry" );
*entryPoint = (long (QDECL *)(long,...))GetProcAddress( libHandle, "vmMain" ); *entryPoint = (intptr_t (QDECL *)(intptr_t,...))GetProcAddress( libHandle, "vmMain" );
if ( !*entryPoint || !dllEntry ) { if ( !*entryPoint || !dllEntry ) {
FreeLibrary( libHandle ); FreeLibrary( libHandle );
return NULL; return NULL;