From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,287b200f57d5fa05,start X-Google-Attributes: gid103376,public From: do_while@ridgecrest.ca.us (Do-While Jones) Subject: GNAT, Windsock, and DLLs Date: 1998/04/14 Message-ID: <6gvp5f$evp$1@owens.ridgecrest.ca.us> X-Deja-AN: 343932051 Organization: RidgeNet - SLIP/PPP Internet, Ridgecrest, CA. (760) 371-3501 Keywords: GNAT, Windsock, DLL, Ada, Windows 95 Newsgroups: comp.lang.ada Date: 1998-04-14T00:00:00+00:00 List-Id: The general question is, "How does GNAT link Ada 95 programs with Windows 95 DLLs?" More specifically, "How can GNAT make use of the Berkeley-like socket services in windsock.dll?" In particular, "What do I need to do to get a demo program (included at the end of this message) to call the gethostname service in windsock.dll?" Background Several years ago, I wrote a collection of Network Interface packages which allow Ada 83 programs (compiled using the Telesoft Telegen 2 compiler on a Sun Sparcstation 2) to call the Berkeley BSD socket routines. These thick bindings gave me handy abstractions that send and receive UDP broadcasts, and implement TCP/IP clients and servers. A couple years ago I ported these packages from our Sun workstations to GNAT (Ada 95) on Silicon Graphics in no time at all. This was easily done because the Silicon Graphics was using a UNIX operating systems with Berkeley sockets. A few months ago I tried to port these same packages to GNAT (Version 3.10) on a Windows 95 machine. Windows 95 comes with a dynamically linked library (DLL) called windsock, which emulates all the Berkeley socket services. One of the simplest of these is gethostname, which returns a character string containing the name of the host computer. The Problem Use gnatchop to divide the program at the end of this message into three compilation units. Then use gnatmake to compile and link ni09td01. (Network Interfaces, component 9, Test Demo program 1.) The program compiles, but fails at the link stage with an error message that says there is an "undefined reference to 'gethostname' in get_host.adb". Clearly, GNAT doesn't know about the gethostname service in windsock.dll. The GNAT UserUs Guide section on "Search Paths for gnatbind" (yes, I'm one of those few people who read the documentation) says that you can tell the linker to look for modules in other directories in several ways. One of these ways is to set the environment variable ADA_OBJECTS_PATH. So, I set ADA_OBJECTS_PATH to "C:\WINDOWS\SYSTEM" where the windsock.dll is (on my system, at least). That didn't work. I suspect gnatbind is looking for a ".o" file, not a ".dll" file. I know very little about C, and even less about Windows 95. I suspect this problem is more of a C/Windows 95 problem than an Ada problem. What is the solution? Do I have to write a zillion (well, actually eight, since I only use socket, bind, accept, fcntrl, open, close, read, write, and gethostname) little C programs that call each windsock service individually, and put their ".o" files somewhere that GNAT can find them? Is there a way to get GNAT to use the windsock.dll directly? If there is a simple solution, I'm sure many readers of Comp.lang.ada would find it useful. Thanks in advance, Do-While Jones ------------------------------------------------------------- -- ni09ks01.ada -- 13 December 1994 -- Do-While Jones -- 324 Traci Lane -- Ridgecrest, CA 93555 -- do_while@ridgecrest.ca.us --with NETWORK; -- part NI02 package GET_HOST is function Name return string; -- Tells you the name of the computer that is executing -- the program. --function Network_Address return NETWORK.Address_numbers; -- Tells you the network address of the computer that -- is executing the program. end GET_HOST; -- ni09kb01.ada -- 13 December 1994 -- Do-While Jones -- 324 Traci Lane -- Ridgecrest, CA 93555 -- do_while@ridgecrest.ca.us with SYSTEM; package body GET_HOST is --- Interface to UNIX service --- function gethostname( name_receiver : SYSTEM.Address; namelen : integer) return integer; pragma Interface(C, gethostname); --------------------------------- function Name return string is -- Assume the name will be 20 characters -- or less. C_STRING : string(1..21) := (others => ASCII.NUL); UNIX_RESULT : integer; LENGTH : integer; begin -- Call a UNIX service to put the name -- in C_STRING. UNIX_RESULT := gethostname( C_STRING(1)'ADDRESS, C_STRING'LENGTH); if UNIX_RESULT /= 0 then -- UNIX failure. return "HOST_NAME_ERROR"; end if; -- Find out how long the string is. LENGTH := 0; for i in C_STRING'RANGE loop exit when C_STRING(i) = ASCII.NUL; LENGTH := i; end loop; -- Return the non-null characters of the string. return C_STRING(1..LENGTH); end Name; --function Network_Address --return NETWORK.Address_numbers is --begin --return NETWORK.Host_Number(Name); --end Network_Address; end GET_HOST; -- ni09td01.ada -- 13 December 1994 -- Do-While Jones -- 324 Traci Lane -- Ridgecrest, CA 93555 -- do_while@ridgecrest.ca.us with TEXT_IO, --NETWORK, -- part NI02 GET_HOST; -- part NI09 procedure NI09TD01 is begin TEXT_IO.Put_Line("This machine is " & GET_HOST.Name & "."); --TEXT_IO.Put_Line("It is at address " --& NETWORK.Image(GET_HOST.Network_Address) --& "."); end NI09TD01;