Subject: Re: How do I avoid buying MSVC++?
From: [email-masked] (Max Hadley)

31 Dec 1998 19:10:23 -0800
Message-ID: <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
To: "Cygwin mailing list" <[email-masked]>

Hello again Cygwin list,

I'm back from my Christmas travels, and ready to tackle compiling this
demo program once more. First off, thanks to all who contributed help &
advice, on & off list. I think I'm begining to see my way now.

Point 1: RTFM (or at least RTFWS). I checked on the cygnus web site &
found how to generate a .a import library for my third-party DLL from
the supplied .lib:

    echo EXPORTS > ntgpib.def
    E:/cygwin/cygwin-b20/H-i586-cygwin32/bin/nm ntgpib.lib | grep ' T _'
| sed 's/.* T _//' >> ntgpib.def
    dlltool --def ntgpib.def --dllname ntgpib.dll --output-lib ntgpib.a

This got rid of all the "ignoring duplicate section `.text'" errors. I
should re-iterate I'm using the MKS toolset, not the Cygwin tools, by
default. hence I have to call Cygwin nm by an absolute pathname. MKS
grep & sed work just the way they should, but the output format of nm is
a bit different.

Point 2: I found if I included "-luser32 -lgdi32" on the gcc link
command line, I got no "undefined reference" errors, and a .exe file was
produced.

Point 3: I should have said that the header file as supplied caused gcc
to whinge:

    susato[232] $ make ntcdemo.exe
    gcc -c  -mwindows -g -pedantic -Wall ntcdemo.c
    In file included from ntcdemo.c:31:
    windecl.h:28: warning: return-type defaults to `int'
    windecl.h: In function `_declspec':
    windecl.h:29: parse error before `_declspec'
    windecl.h:28: declaration for parameter `ibsta' but no such
parameter
    ...
    (many more errors)

The include file windecl.h has some very strange Windows stuff I don't
understand (I haven't programmed Windows in C since its 16-bit days):

    #ifdef _WINDOWS                 /* This is for QuickWin */
        #ifndef _WIN32              /* if (WINVER < 0x0400) */
            #define GPIBAPI _far _pascal
        #else
            #define GPIBAPI __stdcall
        #endif
    #else
        #define GPIBAPI __stdcall
    #endif

    /* Global status variables */
    #ifdef _WIN32
        _declspec( dllimport ) int  ibsta;
        _declspec( dllimport ) int  iberr;
        _declspec( dllimport ) int  ibcnt;
        _declspec( dllimport ) long ibcntl;
    #else
        extern int  ibsta;
        extern int  iberr;
        extern int  ibcnt;
        extern long ibcntl;
    #endif

What is a _declspec? I got around this by commenting out the #ifdef
part, so the simple extern declarations are picked up, & this compiled
without errors:

    susato[246] $ make ntcdemo.exe
    gcc -c  -mwindows -g -pedantic -Wall ntcdemo.c
    gcc -o ntcdemo.exe ntcdemo.o ntgpib.a -luser32 -lgdi32

I was left with a brand-new ntcdemo.exe. Typing ntcdemo at the shell
prompt produced a short burst of disk activity, and an error exit:

    susato[247] $ ntcdemo
    susato[248] $ echo $?
    128

Running under gdb gave me a little extra help:

    susato[249] $ gdb ntcdemo.exe
    GNU gdb 4.17.1
    Copyright 1998 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and
you are
    welcome to change it and/or distribute copies of it under certain
conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for
details.
    This GDB was configured as "i586-cygwin32"...
    (gdb) run
    Starting program: //E/Users/max/progs/WAVstuff/temp/ntcdemo.exe
    61000000://E/Users/max/progs/WAVstuff/temp/cygwin1.dll

    [failed reading symbols from DLL]
    "//E/WINNT/system32/advapi32.dll": error reading line numbers

    [failed reading symbols from DLL]
    "//E/WINNT/system32/KERNEL32.dll": error reading line numbers

    77e70000://E/WINNT/system32/USER32.dll
    77ed0000://E/WINNT/system32/GDI32.dll
    77e10000://E/WINNT/system32/RPCRT4.dll
    10000000://E/Users/max/progs/WAVstuff/temp/ntgpib.dll
    gdb: unknown target exception 0xc0000139 at 0x77f88e01

    Program received signal SIGSEGV, Segmentation fault.
    0x77f8f898 in ?? ()
    (gdb)

Double-clicking the file ntcdemo.exe in Explorer produced an error
message box:

    ntcdemo.exe - Entry Point Not Found
    The procedure entry point ibclr@4 could not be located in the
dynamic link library ntgpib.dll

Aha! something to do with the function name massaging trickery? The
exports list for the DLL, as produced by quickview, doesn't have the @4
tail. Another helpful poster suggested adding the -mwindows switch to
the linker command line, as well as (?) the compile line. This produced
the following:

    susato[252] $ make ntcdemo.exe
    gcc -c  -mwindows -g -pedantic -Wall ntcdemo.c
    gcc -o ntcdemo.exe ntcdemo.o ntgpib.a -mwindows
    //E/cygwin/cygwin-b20/H-i586-cygwin32/i586-cygwin32/bin/ld: warning:
cannot find entry symbol _WinMainCRTStartup; defaulting to 00401000
    susato[253] $

But a .exe file is generated, which appears to behave in exactly the
same way as the previous version. So I think I'm nearly there, apart
from a couple of things.

1. How can I get the function name thing straightened out?
2. Is the _declspec Ju-Ju important, or can I use extern int?

I should admit that at the end of the day I want to write a console app
to use this DLL, not a GUI app, but I need to sort out these problems. I
wouldn't choose C as an implementation language for a windows GUI app! A
very simple test (just calls the 'is the DLL loaded properly' function)
has the same problems with the function naming.

Any suggestions would be very welcome, and thanks again (apologies for
the length of this posting)

Max Hadley
Bramshaw
Hampshire
UK

-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".