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=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,130283ad9c6c2e69 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1994-10-18 21:39:30 PST Path: bga.com!news.sprintlink.net!howland.reston.ans.net!europa.eng.gtefsd.com!uhog.mit.edu!news.mathworks.com!usenet.eel.ufl.edu!usenet.cis.ufl.edu!caen!msuinfo!harbinger.cc.monash.edu.au!aggedor.rmit.EDU.AU!goanna.cs.rmit.oz.au!macdale.cs.rmit.edu.au!dale From: Dale Stanbrough Newsgroups: comp.lang.ada Subject: Re: Interfacing Ada to Unix/execl var. arg. list function? Date: 19 Oct 1994 03:30:11 GMT Organization: RMIT, Melbourne, Australia Distribution: world Message-ID: <3823s3$ioq@goanna.cs.rmit.oz.au> References: <37ioh5$h9v@goanna.cs.rmit.oz.au> <37j8pd$ovu@gnat.cs.nyu.edu> <37m2kd$cp3@watnews1.watson.ibm.c> <37uf6e$7ik@theopolis.orl.mmc.com> NNTP-Posting-Host: macdale.cs.rmit.edu.au X-UserAgent: Version 1.1.3 X-XXMessage-ID: X-XXDate: Wed, 19 Oct 94 13:32:33 GMT Date: 1994-10-19T03:30:11+00:00 List-Id: In article <37uf6e$7ik@theopolis.orl.mmc.com> Bob Gilbert, rgilbert@orl.mmc.com writes: > function C_Excel(Path : System.ADDRESS; > Arg_List : ARG_LIST := Null_Arg_List) return Interfaces.c.int is > > type ADDRESS_ARRAY is array (NATURAL range Arg_List'range) of System.ADDRESS; > Arg_Address_List : ADDRESS_ARRAY; > > begin > for i in Arg_List'range loop -- Build Arg_Address_List for C call > case Arg_List is > Arg_List(i) := Arg_List(i).Arg_1'address; > when Arg_2 => > Arg_List(i) := Arg_List(i).Arg_2'address; > . > . > when Arg_n => > Arg_List(i) := Arg_List(i).Arg_n'address; > when Null_Arg => null; > end case; > end loop; > . > . The main problem lies in here - how do you assemble the various arguments into a call to a pragma import'ed C routine? The only solution appears to be to direct pass parameters via aggregates (as your solution suggests) and then call an equivalent non-variable argument list function (e.g. execl - execv). The code below works, but I am unsure of whether it is memory safe, and whether all memory gets reclaimed at the end of the function. function execv( path :string; argv :string_array := null_arg_list) return integer is C_path :constant interfaces.c.char_array(1..path'length+1) := interfaces.c.to_C(path); type address_array is array(1..argv'length + 1) of system.address; C_argv :address_array; index :integer; ------------------------------------------------------------ function C_execv( path :system.address; C_arg_list:system.address) return interfaces.c.int; pragma import(C, C_execv, "execv"); ------------------------------------------------------------ begin -- set up the array of pointers to the strings index := 0; for i in argv'range loop index := index + 1; -- can Ada release the memory pointed returned by -- interfaces.c.to_c after the loop (leaving the pointer -- pointing at nothing), or will it wait until the end of -- the function, or will it never free up the memory? C_argv(index) := interfaces.c.to_c(argv(i).all)(0)'address; end loop; -- append C style null to the end of the array of addresses -- (presumes that system.null_address = C style null). C_argv(C_argv'last) := system.null_address; -- pass the address of the first element of each -- parameter, as C expects. return integer(C_execv( C_path(1)'address, C_argv(1)'address)); end execv; Thanks, Dale ------------------------------------------------------------- Dale Stanbrough, RMIT, Melbourne, Australia, dale@rmit.edu.au GNU Ada 94 (GNAT) => the best $0 you'll ever spend. Available for DOS, Linux, OS/2, Sun Sparc, Sun Solaris, ... Coming to a GNU supported platform near you soon...