From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id F31D0BC54 for ; Thu, 29 Oct 2009 09:55:44 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AuABAH/16ErZSMDji2dsb2JhbACBT5l1AQEBCgsKBxEFv32EPwQ X-IronPort-AV: E=Sophos;i="4.44,645,1249250400"; d="scan'208";a="37187205" Received: from fmmailgate02.web.de ([217.72.192.227]) by mail3-smtp-sop.national.inria.fr with ESMTP; 29 Oct 2009 09:55:44 +0100 Received: from smtp07.web.de (fmsmtp07.dlan.cinetic.de [172.20.5.215]) by fmmailgate02.web.de (Postfix) with ESMTP id D940913AA9D62; Thu, 29 Oct 2009 09:55:43 +0100 (CET) Received: from [95.208.117.111] (helo=frosties.localdomain) by smtp07.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #314) id 1N3QnH-0003F6-00; Thu, 29 Oct 2009 09:55:43 +0100 Received: from mrvn by frosties.localdomain with local (Exim 4.69) (envelope-from ) id 1N3QnH-0003Ss-Dl; Thu, 29 Oct 2009 09:55:43 +0100 From: Goswin von Brederlow To: Basile STARYNKEVITCH Cc: Adrien , Caml Mailing List Subject: Re: [Caml-list] Binding C libraries which use variable arguments (stdarg.h) References: <666572260910281507q74cb1c1at157c9e3c86070c69@mail.gmail.com> <4AE8C987.8020100@starynkevitch.net> Date: Thu, 29 Oct 2009 09:55:43 +0100 In-Reply-To: <4AE8C987.8020100@starynkevitch.net> (Basile STARYNKEVITCH's message of "Wed, 28 Oct 2009 23:45:27 +0100") Message-ID: <877huewpdc.fsf@frosties.localdomain> User-Agent: Gnus/5.110006 (No Gnus v0.6) XEmacs/21.4.22 (linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: goswin-v-b@web.de X-Sender: goswin-v-b@web.de X-Provags-ID: V01U2FsdGVkX1+HiuN0k/hZTjvOU2ib4ZqDcZkZo6lZHgmAeD46 lsD6ZJFZaaOJ1eSsIFIEAhzH/HkufkNnTkDBoKjTbOx1BiIEVA 31Ytz+sd0= X-Spam: no; 0.00; basile:01 basile:01 foo:01 stub:01 foo:01 ocaml:01 failwith:01 ocaml:01 variants:01 varargs:01 weis:01 printf:01 stub:01 mfg:98 invoke:01 Basile STARYNKEVITCH writes: > Adrien wrote: >> Hi, >> >> I am currently trying to bind a C function that takes variables >> arguments, like foo(int a, ...). I can't find how to make a C stub for >> that function. > > I am assuming that the a is the number of actual arguments, so you call > foo(3, x, y, z) > foo(5, t, t+1, t+3, 0, 4) > foo(0) > >> >> Any other idea? Hint^WPointer? (sorry for the bad joke ;-) ) > > First, you could suppose that the a has a reasonable limit, say 100. > > Then you could generate the glue code for each value of the argument > a. I mean generate ocaml code like > > external f0: void -> uit = "f_0" > external f1: int -> unit = "f_1" > external f2: int -> int -> unit = "f_2" > external f3: int -> int -> int -> unit = "f_3" > > let f a = match Array.length a with > 0 -> f0 () > | 1 -> f1 a.[0] > | 2 -> f2 a.[0] a.[1] > | 3 -> f3 a.[0] a.[1] a.[2] > .... > | _ -> failwith "too many components for f" > > and generate C code for each of f_0 f_1 ... > > and call f with an array ... > > The specialized code generator is reasonably written in Ocaml > > There are more crazy variants, including > > try Ocaml varargs like Pierre Weis did in printf.ml. For plain mortals > like me this is white magic. > > Assuming a Linux system, you could lazily generate the glue code and > invoke dynamic linker on it. So the general case would be to call the > code generator. > > Time to go to bed. I am saying lot of non-sense. > > Bye! Since ocaml functions with more than 5 args use an array you only do that in ocaml for a few arguments and then you need to do this in C. So do it in C for all. The stub takes an array and then switches on the lentgh to call the real function. Unfortunately you can not convert an array or list into a va_list. You need to specifically catch each length and call foo(4, a[0], a[1], a[2], a[3]) for each length. MfG Goswin