• Welcome to OS2World OLD-STATIC-BACKUP Forum.
 

News:

This is an old OS2World backup forum for reference only. IT IS READ ONLY!!!

If you need help with OS/2 - eComStation visit http://www.os2world.com/forum

Main Menu

GCC and DosQueryProcAddr

Started by dirckm, 2009.10.15, 17:57:32

Previous topic - Next topic

dirckm

Hello All,

Im trying to get a DosQueryProcAddr return address to execute its function.
Im compiling with gcc. Im trying now for some days to get this working but without luck..
(I compile with gcc -Wall -Zomf -los2 test.c -o test)

A simple example on VIOCALLS calling VIOGETANSI..which isnt working..


#define  INCL_DOSMODULEMGR
#include <os2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void (* _Far16 my_viogetansi)( unsigned short, unsigned short);

int main(void)
{
   unsigned int  ret;
   unsigned int    rc = 0, HANDLE = 0;
   unsigned char    error[256]="";
   HMODULE hmod;

  rc = DosLoadModule((PSZ)error,sizeof(error),"VIOCALLS", &hmod);
    if (rc) { printf("%s\n", (PSZ)error); exit(-1); }

   rc = DosQueryProcAddr(hmod, 0L ,"VIOGETANSI",(PFN *) &my_viogetansi);
     if (rc) { printf("%d\n", rc); exit(-1); }

   my_viogetansi(&ret,HANDLE);
   printf("VIOGETANSI returned: %d\n", ret);

   rc = DosFreeModule(hmod);
     if (rc) { printf("%d\n", rc); exit(-1); }
   
   return(0);
}


The output is a SEGV..

I tried different ways in creating a Function with Far, Im used to the old Turbo C and Microsoft C versions
and it seems that the only way to call in gcc is using (* _Far16 _Pascal func) to get the function going.

Now my question:
* Why it the above code not working (its it possible at all from within gcc?)? Do I realy do something wrong?
* Is there a quicker/better way in calling loaded-addresses from DLL's within C/gcc under OS/2?
(I mean..putting it all on the data-stack and then calling the function is an option but i dont want to use ASM..)

Any help is very appriciated..

Dirck.






dirckm


Aaaa thanks Silvan... I did seek lots of code examples and they all did it
differently.. But none actualy based on the os2emx.h..
Looking at the code I expect that will work ;-)



dirckm


I was too optimistic ;-) Unfortunatly..

its about this call ->

my_viogetansi(&ret,HANDLE);

Seems somehow gcc give me always a SEGV on that point..
If I define the Far function with APIENTRY or _Far16 or whatever.. It doesnt eat the call to the function..
Opening and reading the function from the DLL works no problem.. But calling the alternative function by address doesnt..

Its probably my rusty C..

Any hints are still welcome ;-)



Radek

Both parameters of my_viogetansi() are USHORTs and you are passing a 32-bit address (&ret) and a 32-bit int to it. Both parameters get truncated to 16-bit and zero extended when passed to my_viogetansi(). This is disastrous for the address and you get a GP fault during my_viogetansi() processing.

Check the assembler code of main(). Possible causes of problems with the call:
(1) my_viogetansi() is 16-bit and it is called as a 32-bit near pointer. GP fault. Needs explicit thunking.
(2) my_viogetansi() expects 2 words on the stack and gets 2 dwords. GP fault. Needs parameter trickery in my_viogetansi().
(3) The paramters get truncated when passed to my_viogetansi(), GP fault caused by the address.
(4) Who is removing the parameters from the stack? Declarators APIENTRY and EXPENTRY are the same as PASCAL. Therefore if the function is APIENTRY then if must remove its parameters from the stack. If the caller, that means, main() should remove the paremeters from the stack, then the funciton must not be APIENTRY.

If you have access to the DLL code then redo my_viogetansi() as

// well defined DLL functions in OS/2 are APIENTRY (or EXPENTRY) in OS/2 :)

void APIENTRY my_viogetansi( ULONG addr, ULONG handle )
{
...
}

and try again :)

At any rate, you should have got a warning from the compiler about truncating procedure params when compiling main(). If you haven't got such warning then throw the compiler down the drain and try another one.