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 X-Google-Attributes: gid103376,public From: "Barry Scott" Subject: Re: GNAT, Windsock, and DLLs Date: 1998/04/14 Message-ID: X-Deja-AN: 343949765 References: <6gvp5f$evp$1@owens.ridgecrest.ca.us> X-MimeOLE: Produced By Microsoft MimeOLE V4.72.2106.4 Organization: Intergraph Newsgroups: comp.lang.ada Date: 1998-04-14T00:00:00+00:00 List-Id: I'm not sure it matters for your code, but the dll is winsock.dll, not windsock.dll. Barry Do-While Jones wrote in message <6gvp5f$evp$1@owens.ridgecrest.ca.us>... >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; > >