From: Goswin von Brederlow <goswin-v-b@web.de>
To: Adrien <camaradetux@gmail.com>
Cc: Caml Mailing List <caml-list@yquem.inria.fr>
Subject: Re: [Caml-list] Binding C libraries which use variable arguments (stdarg.h)
Date: Fri, 30 Oct 2009 00:31:41 +0100 [thread overview]
Message-ID: <87zl793hgi.fsf@frosties.localdomain> (raw)
In-Reply-To: <666572260910291437w38283b27s1244f39f68a86b3e@mail.gmail.com> (Adrien's message of "Thu, 29 Oct 2009 22:37:15 +0100")
Adrien <camaradetux@gmail.com> writes:
> On 29/10/2009, Goswin von Brederlow <goswin-v-b@web.de> wrote:
>> Basile STARYNKEVITCH <basile@starynkevitch.net> 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.
>
> Well, my problem is more when calling the C function since I can chose
> the interface of the caml functions.
If you can't change the C function to use something other than varargs
and you can't limit the number of args and implement a case for each
number then the only option left is to create the varargs from an
array. That will be really ugly and architecture and compiler
dependent. So lots of #ifdef cases in your C code. Something you
really do not want to do.
> There's something I've not been sure and would like to ask however:
> for the sake of consitency, I've been giving both a native and
> bytecode function every time no matter the number of arguments. Could
> that be a problem?
No. With >= 5 args you just need 2 functions, one for native and one
for bytecode. The docs have an example on how to do that. The problem
is calling the actual C function.
MfG
Goswin
next prev parent reply other threads:[~2009-10-29 23:31 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-28 22:07 Adrien
2009-10-28 22:45 ` Basile STARYNKEVITCH
2009-10-29 8:55 ` Goswin von Brederlow
2009-10-29 21:37 ` Adrien
2009-10-29 23:31 ` Goswin von Brederlow [this message]
2009-10-29 21:18 ` Adrien
2009-10-30 9:35 ` Xavier Leroy
2009-11-01 9:31 ` Adrien
2009-11-01 11:07 ` Florian Weimer
2009-11-01 12:12 ` Adrien
2009-11-01 12:16 ` Florian Weimer
2009-11-01 14:58 ` Adrien
2009-11-01 20:06 ` Richard Jones
2009-11-03 19:33 ` Florian Weimer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87zl793hgi.fsf@frosties.localdomain \
--to=goswin-v-b@web.de \
--cc=camaradetux@gmail.com \
--cc=caml-list@yquem.inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).