[comp.windows.ms.programmer] GlobalDosAlloc not exported in libs?

dkb@bistromath.mitre.org (Daryl K. Baker) (02/14/91)

Has anyone used GlobalDosAlloc and GlobalDosFree?  I tried linking
my application which was using these rouintes and received
unresolved externals. (A side note: if you do a "strings" on
the library you can find references to these functions). Does
anyone have any info on this problem?

Daryl Baker
dkb@mitre.org 

rommel@Informatik.TU-Muenchen.DE (Kai-Uwe Rommel) (02/14/91)

In article <1991Feb13.165724.18629@linus.mitre.org> dkb@bistromath.mitre.org (Daryl K. Baker) writes:
>Has anyone used GlobalDosAlloc and GlobalDosFree?  I tried linking
>my application which was using these rouintes and received
>unresolved externals. (A side note: if you do a "strings" on

The prototypes are missing in the WINDOWS.H header file. Just add them as
shown in the online help or in the printed manuals. If not (and if you
use warning level < 3 you will not even get a warning about missing
prototypes) the compiler assumes them to be of type cdecl and adds the
leading underscore and therefore the linker does not find them.

Kai Uwe Rommel

jls@hsv3.UUCP (James Seidman) (02/15/91)

In article <1991Feb13.165724.18629@linus.mitre.org> dkb@bistromath.mitre.org (Daryl K. Baker) writes:
>Has anyone used GlobalDosAlloc and GlobalDosFree?  I tried linking
>my application which was using these rouintes and received
>unresolved externals. (A side note: if you do a "strings" on
>the library you can find references to these functions). Does
>anyone have any info on this problem?

The problem is that for some reason (which I won't even speculate about),
prototypes for those two functions are not included in windows.h. The reason
you need the prototype is because they, like almost all other API functions,
are declared using the _pascal calling convention.  Under this convention,
an underscore is not prepended to the name.  What's happening is that,
since you have no prototype, your OBJ has a reference to _GlobalDosAlloc
rather than GlobalDosAlloc and can't find it.

Just write your own function prototype (by looking at the SDK reference)
and make sure to declare it as a pascal-convention function, and it should
work just fine.

-- 
Jim Seidman (Drax), the accidental engineer.
"It doesn't have to work... they'll be paralyzed just from laughing at me."
							- Dr. Who, _Shada_
UUCP: ames!vsi1!hsv3!jls	         INTERNET: hsv3.UUCP!jls@apple.com

TKOP-ML@finou.oulu.fi (Mikko Laanti) (02/17/91)

Microsoft left them (intentionally?) undefined.
You have to explicitly IMPORT them in Your DEFinition file.

IMPORTS

       GLOBALDOSALLOC = KERNEL.184
       GLOBALDOSFREE = KERNEL.185


To find more undefined function, please, run


 EXEHDR.EXE -V KERNEL.EXE



Mikko Laanti

mjc@siesoft.co.uk (Mark Carlin) (03/10/91)

GlobalDosAlloc () and GlobalDosFree () are accessible from the library.
The problem is with windows.h not defining function prototypes for them.

The trick is to define the function prototypes yourself and to remember
that they are of type PASCAL.

Try the following declarations:

DWORD PASCAL GlobalDosAlloc (DWORD dwbytes);
WORD PASCAL GlobalDosFree (WORD wSelector);

These functions should only be used if you really can't find a more
windows friendly way of achieving your objectives.

I would hazard a guess and suggest that if your intention is to
communicate with a a DOS program, such as a TSR, then you may have another
problem to follow; altering segment registers and issuing a software
interrupt in in enhanced mode will cause a protection violation.
To overcome this you may have to mess around with DPMI (DOS Protected
Mode Interface).

Mark Carlin

This posting is not issued on behalf of, or for, Siemens Nixdorf
Informations Systems.

rommel@Informatik.TU-Muenchen.DE (Kai-Uwe Rommel) (03/12/91)

In article <1991Mar10.143402.12577@siesoft.co.uk> mjc@siesoft.co.uk (Mark Carlin) writes:
>I would hazard a guess and suggest that if your intention is to
>communicate with a a DOS program, such as a TSR, then you may have another
>problem to follow; altering segment registers and issuing a software
>interrupt in in enhanced mode will cause a protection violation.
>To overcome this you may have to mess around with DPMI (DOS Protected
>Mode Interface).
You *can* issue software interrupts in 386 enhanced mode, at least to
the most often used vectors, such as 2F, the multiplex interrupt. I use
this a lot. Installing TSR's as INT-2F-handlers is always a good idea
because you cannot conflict with other TSR's that easy as if you choose
some other arbitrary one if you follow the INT-2F specifications.
Also, when issuing a software interrupt, you can pass the segment value
for the GlobalDosAlloc()ated block in an universal register and load it
into a segment register in real mode in your TSR.

Kai Uwe Rommel

dkb@bistromath.mitre.org (Daryl K. Baker) (03/13/91)

I posted the orignal querry and thanks to all who responded with
the "correct" answer (no included in windows.h add defintions).

Now for the why.  I am trying to call a tsr.

In article <1991Mar12.081711.8270@Informatik.TU-Muenchen.DE> rommel@Informatik.TU-Muenchen.DE (Kai-Uwe Rommel) writes:
>In article <1991Mar10.143402.12577@siesoft.co.uk> mjc@siesoft.co.uk (Mark Carlin) writes:
>>I would hazard a guess and suggest that if your intention is to
>>communicate with a a DOS program, such as a TSR, then you may have another
>>problem to follow; altering segment registers and issuing a software
>>interrupt in in enhanced mode will cause a protection violation.
>>To overcome this you may have to mess around with DPMI (DOS Protected
>>Mode Interface).
>You *can* issue software interrupts in 386 enhanced mode, at least to
>the most often used vectors, such as 2F, the multiplex interrupt. I use

Unfortunately the interupt rouinte already exists and I can't change it.
What I did was to write a little routine called dpmi_int86x ();  with
the same calling parameters as the microsoft routine int86x.  This
routine calls the dpmi handler to do a "call real mode interupt"
(this routine is based on a recent article in PC Magazine)

The thing you must make sure of is that all pointers point to dos
memory.

=== dpmi_int86x ===
#include <windows.h>
#include <dos.h>

struct DPMI_REGS {
   WORD   di;   WORD  xdi;
   WORD   si;   WORD  xsi;
   WORD   bp;   WORD  xbp;

   DWORD reserved;

   WORD   bx;   WORD  xbx;
   WORD   dx;   WORD  xdx;
   WORD   cx;   WORD  xcx;
   WORD   ax;   WORD  xax;
   WORD  flags;
   WORD  es;
   WORD  ds;
   WORD  fs;
   WORD  gs;
   WORD  ip;    WORD  cs;
   WORD  sp;    WORD  ss;
   WORD  protdx;
   WORD  protsi;
   WORD  protes;
};

int dpmi_int86x ( int int_num, union REGS *inregs, union REGS *outregs,
                  struct SREGS *segregs)
{

   struct DPMI_REGS far * dos_dpmi_regs;
   struct DPMI_REGS       dpmi_regs;
   WORD regs_seg, regs_off;

   dos_dpmi_regs = &dpmi_regs;
   dos_dpmi_regs->ax = inregs->x.ax;
   dos_dpmi_regs->bx = inregs->x.bx;
   dos_dpmi_regs->cx = inregs->x.cx;
   dos_dpmi_regs->dx = inregs->x.dx;
   dos_dpmi_regs->si = inregs->x.si;
   dos_dpmi_regs->di = inregs->x.di;
   dos_dpmi_regs->es = segregs->es;
   dos_dpmi_regs->ds = segregs->ds;

   dos_dpmi_regs->protdx = inregs->x.dx;
   dos_dpmi_regs->protsi = inregs->x.si;
   dos_dpmi_regs->protes = segregs->es;


   dos_dpmi_regs->ss = 0;
   dos_dpmi_regs->sp = 0;              /* Uses dpmi server stack */

   regs_seg = FP_SEG (dos_dpmi_regs);
   regs_off = FP_OFF (dos_dpmi_regs);

   _asm {
      push  es
      mov   ax, regs_seg
      mov   es, ax

      mov   ax, 0300h
      mov   bx, int_num
      mov   bh, 0
      mov   cx, 0
      mov   di, regs_off
      int   31h
      pop   es
   }

   outregs->x.ax = dos_dpmi_regs->ax;
   outregs->x.bx = dos_dpmi_regs->bx;
   outregs->x.cx = dos_dpmi_regs->cx;
   outregs->x.dx = dos_dpmi_regs->dx;
   outregs->x.si = dos_dpmi_regs->si;
   outregs->x.di = dos_dpmi_regs->di;
   outregs->x.cflag = dos_dpmi_regs->flags & 1;

   return outregs->x.ax;
}

=== sample caller ===

   char far * dos_char_ptr;

   DWORD hDosMemory;
   HANDLE hProt, hReal;

   hDosMemory = GlobalDosAlloc ( (long) maxlen );
   hProt      = LOWORD (hDosMemory);
   hReal      = HIWORD (hDosMemory);
   dos_char_ptr = GlobalLock ( hProt );
   lstrcpy ( dos_char_ptr, name);

   inregs.h.ah = _nm_res_name;
   
   inregs.x.cx = maxlen;

   inregs.x.dx = FP_OFF(dos_char_ptr);
   inregs.x.di = FP_OFF(dos_char_ptr);

   segregs.ds = hReal;
   segregs.es = hReal;

   result = dpmi_int86x ( pctcp_int, &inregs, &outregs, &segregs);


   GlobalUnlock ( hProt);
   GlobalDosFree (hProt);


Daryl Baker
dkb@bistromath.mitre.org