From: dic5340@hertz.njit.edu (David Charlap)
Newsgroups: comp.os.os2.programmer
Subject: Re: **SEGMENT VIOLATIONS and DLLs**
Date: 9 Jan 93 09:23:21 GMT
Organization: New Jersey Institute of Technology, Newark, N.J.

In article <1993Jan8.171124.1078@beckman.com> rariedel@beckman.com (Bob Riedel) writes:
>I am having difficulty getting an application object library to work
>without generating segment violation errors under OS/2 V1.3 using the
>Microsoft C6 compiler.
>
>The modules which make up the library are being compiled using the
>/MT /AL /Aw /G2 /Gc switches because they are ultimately destined to be
>part of a DLL (they are not currently).

Good, I only use Large and Huge models when writing OS/2 code - it
saves a lot of problems later.  I found that /Aw doesn't always work.
Using /Au will force _loadds with every function call - perhaps a bit
overkill, but it eliminates much of these errors.

>I am having some difficulty deciding when to use the _loadds attribute
>on the individual functions, and the absence of this attribute on some
>of the components of the library seems to be the primary cause of the
>problem.

Use _loadds on any function that will be exported to procedures
outside the DLL.  I believe such functions should all be declared with
the EXPENTRY keyword, which is, in effect _loadds pascal.

>All of the problems (so far) appear when one module passes stack variables
>by reference to another module. For some reason the receiving module cannot
>reference the caller's data. It even happens when private modules (those not
>referenced outside the DLL) in a separate thread wake up on a timer and pass
>stack variables by reference to another function (which then blows up). The
>offending private modules have static data.

Yes.  Each DLL has it's own stack and global data, I believe.  You
should not pass variables by reference to DLL's, since your data
segment, and possible also stack segment are different.  Be sure that
the compiler always assumes that ss!=ds.

>These are my questions:
>
>	1 - When do you use the _loadds attribute, and when do you not
>	    have to?

Code that has no out-of-the-module references doesn't need it.
Anything that's going to be called from another module should use it.
The easiest way is to declare all exported functions with the EXPENTRY
keyword.

>	2 - Can the private parts of the library, that is those functions
>	    which cannot be called outside the library, be compiled using
>	    a standard model (ie: /MT /AL), while only the exported sections
>	    are compiled using /ALw?

No.  The entire library should be compiled with the same model.  If
you flag the exported sections appropriately, that will be enough.
Mixing memory models is painful enough.  Don't make things worse by
trying to do this in a DLL.

>	3 - If the answer to (2) is no, then does that mean that even some
> 	    private modules must have the _loadds attribute?

It really doesn't hurt.  If you suspect there being a problem, compile
it with the /ALu switches in place.  This way, everything will get a
_loadds.

>	4 - Does the main() need any special attributes if it is compiled
>	    using /ALw?

I don't think so.

>	5 - Why can't the Microsoft C "Advanced" Programming Techniques
>	    manual answer some of these stupid questions?

Because it assumes you already know this.  It also assumes that you'll
have the Microsoft OS/2 toolkit to answer these questions.  The
"advanced" programming techniques deals mostly with DOS code and
leaves Windows and OS/2 stuff to the respective toolkits.  Since IBM's
C/2 compiler is a repackaged MS-C, you might check the IBM 1.3 toolkit
for help.

Don't forget that if your DLL calls any C library functions,
whatsoever, you must link it with LLIBCDLL and not LLIBCEP.



-- 
  |)  David Charlap          | .signature confiscated by FBI due to
 /|_  dic5340@hertz.njit.edu | an ongoing investigation into the
((|,)                        | source of these .signature virusses
 ~|~
Newsgroups: comp.os.os2.programmer,comp.os.os2.advocacy