caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* How to pass C pointers to Caml
@ 2010-03-01  3:55 Jianzhou Zhao
  2010-03-01  6:22 ` [Caml-list] " Florent Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Jianzhou Zhao @ 2010-03-01  3:55 UTC (permalink / raw)
  To: caml-list

I have been calling OCaml code from C in my project.
The C code has some pointers to C structures.
I got 'seg fault' when calling the OCaml function receiving
C structure pointers.

18.7 at http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html
gives the examples that pass int into OCaml. These examples work for me.
But, Does OCaml support to pass C structure pointers to OCaml?

-- 
Jianzhou


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] How to pass C pointers to Caml
  2010-03-01  3:55 How to pass C pointers to Caml Jianzhou Zhao
@ 2010-03-01  6:22 ` Florent Monnier
  2010-03-01 13:23   ` Jianzhou Zhao
  2010-03-01 13:24   ` Goswin von Brederlow
  0 siblings, 2 replies; 8+ messages in thread
From: Florent Monnier @ 2010-03-01  6:22 UTC (permalink / raw)
  To: caml-list

Le lundi 1 mars 2010 04:55:00, Jianzhou Zhao a écrit :
> I have been calling OCaml code from C in my project.
> The C code has some pointers to C structures.
> I got 'seg fault' when calling the OCaml function receiving
> C structure pointers.
> 
> 18.7 at http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html
> gives the examples that pass int into OCaml. These examples work for me.
> But, Does OCaml support to pass C structure pointers to OCaml?

Yes it does. Just cast your pointer to the type value.

In this tutorial there is an example "Pointers to C structures":
http://www.linux-nantes.org/~fmonnier/OCaml/ocaml-wrapping-c.php#ref_ptr

the pointer to a C struct is wrapped on the ocaml side by an abstract type 
called "t" here, and it is provided back to C with print_t / dump_ptr.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] How to pass C pointers to Caml
  2010-03-01  6:22 ` [Caml-list] " Florent Monnier
@ 2010-03-01 13:23   ` Jianzhou Zhao
  2010-03-01 13:24   ` Goswin von Brederlow
  1 sibling, 0 replies; 8+ messages in thread
From: Jianzhou Zhao @ 2010-03-01 13:23 UTC (permalink / raw)
  To: Florent Monnier; +Cc: caml-list

On Mon, Mar 1, 2010 at 1:22 AM, Florent Monnier
<monnier.florent@gmail.com> wrote:
> Le lundi 1 mars 2010 04:55:00, Jianzhou Zhao a écrit :
>> I have been calling OCaml code from C in my project.
>> The C code has some pointers to C structures.
>> I got 'seg fault' when calling the OCaml function receiving
>> C structure pointers.
>>
>> 18.7 at http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html
>> gives the examples that pass int into OCaml. These examples work for me.
>> But, Does OCaml support to pass C structure pointers to OCaml?
>
> Yes it does. Just cast your pointer to the type value.
>
> In this tutorial there is an example "Pointers to C structures":
> http://www.linux-nantes.org/~fmonnier/OCaml/ocaml-wrapping-c.php#ref_ptr
>
> the pointer to a C struct is wrapped on the ocaml side by an abstract type
> called "t" here, and it is provided back to C with print_t / dump_ptr.

Thanks. This tutorial helps a lot when calling C from OCaml.
What I was doing is more like calling OCaml from C, at section
http://www.linux-nantes.org/~fmonnier/OCaml/ocaml-wrapping-c.php#ref_mlfromc.
Because my main program is C. In this case, does OCaml have any restriction
when passing a C pointer (which points to a struct) to OCaml runtme in
this direction?

Jianzhou

>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>



-- 
Jianzhou


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] How to pass C pointers to Caml
  2010-03-01  6:22 ` [Caml-list] " Florent Monnier
  2010-03-01 13:23   ` Jianzhou Zhao
@ 2010-03-01 13:24   ` Goswin von Brederlow
  2010-03-01 23:04     ` Florent Monnier
  1 sibling, 1 reply; 8+ messages in thread
From: Goswin von Brederlow @ 2010-03-01 13:24 UTC (permalink / raw)
  To: caml-list

Florent Monnier <monnier.florent@gmail.com> writes:

> Le lundi 1 mars 2010 04:55:00, Jianzhou Zhao a écrit :
>> I have been calling OCaml code from C in my project.
>> The C code has some pointers to C structures.
>> I got 'seg fault' when calling the OCaml function receiving
>> C structure pointers.
>> 
>> 18.7 at http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html
>> gives the examples that pass int into OCaml. These examples work for me.
>> But, Does OCaml support to pass C structure pointers to OCaml?
>
> Yes it does. Just cast your pointer to the type value.
>
> In this tutorial there is an example "Pointers to C structures":
> http://www.linux-nantes.org/~fmonnier/OCaml/ocaml-wrapping-c.php#ref_ptr
>
> the pointer to a C struct is wrapped on the ocaml side by an abstract type 
> called "t" here, and it is provided back to C with print_t / dump_ptr.

The problem with this trivial approach is that ocaml can store the
pointer somewhere. When the C pointer is freeed then ocaml has a
dangling pointer. Worse, if the GC allocates a new heap then the pointer
might suddenly point into the heap and then BOOM.

It is better to put the pointer into an abstract or custom block.

MfG
        Goswin


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] How to pass C pointers to Caml
  2010-03-01 13:24   ` Goswin von Brederlow
@ 2010-03-01 23:04     ` Florent Monnier
  2010-03-02 10:19       ` Goswin von Brederlow
  0 siblings, 1 reply; 8+ messages in thread
From: Florent Monnier @ 2010-03-01 23:04 UTC (permalink / raw)
  To: caml-list

Le lundi 1 mars 2010 14:24:45, Goswin von Brederlow a écrit :
> Florent Monnier <monnier.florent@gmail.com> writes:
> > Le lundi 1 mars 2010 04:55:00, Jianzhou Zhao a écrit :
> >> I have been calling OCaml code from C in my project.
> >> The C code has some pointers to C structures.
> >> I got 'seg fault' when calling the OCaml function receiving
> >> C structure pointers.
> >>
> >> 18.7 at http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html
> >> gives the examples that pass int into OCaml. These examples work for me.
> >> But, Does OCaml support to pass C structure pointers to OCaml?
> >
> > Yes it does. Just cast your pointer to the type value.
> >
> > In this tutorial there is an example "Pointers to C structures":
> > http://www.linux-nantes.org/~fmonnier/OCaml/ocaml-wrapping-c.php#ref_ptr
> >
> > the pointer to a C struct is wrapped on the ocaml side by an abstract
> > type called "t" here, and it is provided back to C with print_t /
> > dump_ptr.
> 
> The problem with this trivial approach is that ocaml can store the
> pointer somewhere. When the C pointer is freeed then ocaml has a
> dangling pointer. Worse, if the GC allocates a new heap then the pointer
> might suddenly point into the heap and then BOOM.

A lot of bindings wrap C pointer, it is known to be a technic that does work.
Dangerous that's true, be if you are very careful, it works.
What you can do is set the pointer to NULL when the struct is freed, and then 
each function that uses this struct pointer can first check if the pointer is 
NULL or not before to use it, and if it's NULL raise an exception.

> It is better to put the pointer into an abstract or custom block.

You can do this too.

-- 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] How to pass C pointers to Caml
  2010-03-01 23:04     ` Florent Monnier
@ 2010-03-02 10:19       ` Goswin von Brederlow
  2010-03-02 11:34         ` Florent Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Goswin von Brederlow @ 2010-03-02 10:19 UTC (permalink / raw)
  To: Florent Monnier; +Cc: caml-list

Florent Monnier <monnier.florent@gmail.com> writes:

> Le lundi 1 mars 2010 14:24:45, Goswin von Brederlow a écrit :
>> Florent Monnier <monnier.florent@gmail.com> writes:
>> > Le lundi 1 mars 2010 04:55:00, Jianzhou Zhao a écrit :
>> >> I have been calling OCaml code from C in my project.
>> >> The C code has some pointers to C structures.
>> >> I got 'seg fault' when calling the OCaml function receiving
>> >> C structure pointers.
>> >>
>> >> 18.7 at http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html
>> >> gives the examples that pass int into OCaml. These examples work for me.
>> >> But, Does OCaml support to pass C structure pointers to OCaml?
>> >
>> > Yes it does. Just cast your pointer to the type value.
>> >
>> > In this tutorial there is an example "Pointers to C structures":
>> > http://www.linux-nantes.org/~fmonnier/OCaml/ocaml-wrapping-c.php#ref_ptr
>> >
>> > the pointer to a C struct is wrapped on the ocaml side by an abstract
>> > type called "t" here, and it is provided back to C with print_t /
>> > dump_ptr.
>> 
>> The problem with this trivial approach is that ocaml can store the
>> pointer somewhere. When the C pointer is freeed then ocaml has a
>> dangling pointer. Worse, if the GC allocates a new heap then the pointer
>> might suddenly point into the heap and then BOOM.
>
> A lot of bindings wrap C pointer, it is known to be a technic that does work.
> Dangerous that's true, be if you are very careful, it works.
> What you can do is set the pointer to NULL when the struct is freed, and then 
> each function that uses this struct pointer can first check if the pointer is 
> NULL or not before to use it, and if it's NULL raise an exception.

let x = ref None

let called_function c_ptr = x := Some c_ptr

How will you get x to be Some NULL? Your C code does not know about the
copy. You need to wrap the C pointer into a custom or abstract block
first to be able to NULL it. A finalizer in a custom block can also be
helpfull here and free the pointer when ocaml no longer needs it.

>> It is better to put the pointer into an abstract or custom block.
>
> You can do this too.

Imho you must. Anything else is too dangerous.

MfG
        Goswin


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] How to pass C pointers to Caml
  2010-03-02 10:19       ` Goswin von Brederlow
@ 2010-03-02 11:34         ` Florent Monnier
  2010-03-03 11:02           ` Goswin von Brederlow
  0 siblings, 1 reply; 8+ messages in thread
From: Florent Monnier @ 2010-03-02 11:34 UTC (permalink / raw)
  To: caml-list, Goswin von Brederlow

Le mardi 2 mars 2010 11:19:58, vous avez écrit :
> Florent Monnier <monnier.florent@gmail.com> writes:
> > Le lundi 1 mars 2010 14:24:45, Goswin von Brederlow a écrit :
> >> Florent Monnier <monnier.florent@gmail.com> writes:
> >> > Le lundi 1 mars 2010 04:55:00, Jianzhou Zhao a écrit :
> >> >> I have been calling OCaml code from C in my project.
> >> >> The C code has some pointers to C structures.
> >> >> I got 'seg fault' when calling the OCaml function receiving
> >> >> C structure pointers.
> >> >>
> >> >> 18.7 at http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html
> >> >> gives the examples that pass int into OCaml. These examples work for
> >> >> me. But, Does OCaml support to pass C structure pointers to OCaml?
> >> >
> >> > Yes it does. Just cast your pointer to the type value.
> >> >
> >> > In this tutorial there is an example "Pointers to C structures":
> >> > http://www.linux-nantes.org/~fmonnier/OCaml/ocaml-wrapping-c.php#ref_p
> >> >tr
> >> >
> >> > the pointer to a C struct is wrapped on the ocaml side by an abstract
> >> > type called "t" here, and it is provided back to C with print_t /
> >> > dump_ptr.
> >>
> >> The problem with this trivial approach is that ocaml can store the
> >> pointer somewhere. When the C pointer is freeed then ocaml has a
> >> dangling pointer. Worse, if the GC allocates a new heap then the pointer
> >> might suddenly point into the heap and then BOOM.
> >
> > A lot of bindings wrap C pointer, it is known to be a technic that does
> > work. Dangerous that's true, be if you are very careful, it works.
> > What you can do is set the pointer to NULL when the struct is freed, and
> > then each function that uses this struct pointer can first check if the
> > pointer is NULL or not before to use it, and if it's NULL raise an
> > exception.
> 
> let x = ref None
> 
> let called_function c_ptr = x := Some c_ptr
> 
> How will you get x to be Some NULL?

I mean often in a C library pointers to C struct are just pointers to 
something abstract because a lot of lib C API do hide the struct, and provide 
a function to free the things pointed. So in your wrapper after you call the 
destroy function you can set the pointer to NULL and in the other functions 
test if the pointer is NULL before to use it to prevent a user of the wrapper 
to call a function after having called the destroy function.

>                                     Your C code does not know about the
> copy. You need to wrap the C pointer into a custom or abstract block
> first to be able to NULL it. A finalizer in a custom block can also be
> helpfull here and free the pointer when ocaml no longer needs it.
> 
> >> It is better to put the pointer into an abstract or custom block.
> >
> > You can do this too.
> 
> Imho you must. Anything else is too dangerous.

Yes it is dangerous, but as I explained with some C libraries this is the only 
possible solution. If you can do it the other way, then do, while it's indeed 
safer.

-- 
Cheers


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] How to pass C pointers to Caml
  2010-03-02 11:34         ` Florent Monnier
@ 2010-03-03 11:02           ` Goswin von Brederlow
  0 siblings, 0 replies; 8+ messages in thread
From: Goswin von Brederlow @ 2010-03-03 11:02 UTC (permalink / raw)
  To: Florent Monnier; +Cc: caml-list, Goswin von Brederlow

Florent Monnier <monnier.florent@gmail.com> writes:

> Le mardi 2 mars 2010 11:19:58, vous avez écrit :
>> Florent Monnier <monnier.florent@gmail.com> writes:
>> > Le lundi 1 mars 2010 14:24:45, Goswin von Brederlow a écrit :
>> >> Florent Monnier <monnier.florent@gmail.com> writes:
>> >> > Le lundi 1 mars 2010 04:55:00, Jianzhou Zhao a écrit :
>> >> >> I have been calling OCaml code from C in my project.
>> >> >> The C code has some pointers to C structures.
>> >> >> I got 'seg fault' when calling the OCaml function receiving
>> >> >> C structure pointers.
>> >> >>
>> >> >> 18.7 at http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html
>> >> >> gives the examples that pass int into OCaml. These examples work for
>> >> >> me. But, Does OCaml support to pass C structure pointers to OCaml?
>> >> >
>> >> > Yes it does. Just cast your pointer to the type value.
>> >> >
>> >> > In this tutorial there is an example "Pointers to C structures":
>> >> > http://www.linux-nantes.org/~fmonnier/OCaml/ocaml-wrapping-c.php#ref_p
>> >> >tr
>> >> >
>> >> > the pointer to a C struct is wrapped on the ocaml side by an abstract
>> >> > type called "t" here, and it is provided back to C with print_t /
>> >> > dump_ptr.
>> >>
>> >> The problem with this trivial approach is that ocaml can store the
>> >> pointer somewhere. When the C pointer is freeed then ocaml has a
>> >> dangling pointer. Worse, if the GC allocates a new heap then the pointer
>> >> might suddenly point into the heap and then BOOM.
>> >
>> > A lot of bindings wrap C pointer, it is known to be a technic that does
>> > work. Dangerous that's true, be if you are very careful, it works.
>> > What you can do is set the pointer to NULL when the struct is freed, and
>> > then each function that uses this struct pointer can first check if the
>> > pointer is NULL or not before to use it, and if it's NULL raise an
>> > exception.
>> 
>> let x = ref None
>> 
>> let called_function c_ptr = x := Some c_ptr
>> 
>> How will you get x to be Some NULL?
>
> I mean often in a C library pointers to C struct are just pointers to 
> something abstract because a lot of lib C API do hide the struct, and provide 
> a function to free the things pointed. So in your wrapper after you call the 
> destroy function you can set the pointer to NULL and in the other functions 
> test if the pointer is NULL before to use it to prevent a user of the wrapper 
> to call a function after having called the destroy function.
>
>>                                     Your C code does not know about the
>> copy. You need to wrap the C pointer into a custom or abstract block
>> first to be able to NULL it. A finalizer in a custom block can also be
>> helpfull here and free the pointer when ocaml no longer needs it.
>> 
>> >> It is better to put the pointer into an abstract or custom block.
>> >
>> > You can do this too.
>> 
>> Imho you must. Anything else is too dangerous.
>
> Yes it is dangerous, but as I explained with some C libraries this is the only 
> possible solution. If you can do it the other way, then do, while it's indeed 
> safer.

It is always possible to wrap the C pointer into an abstract or custom
block. The pointer can still become dangling when the C side frees the
target before ocaml forgets the block but, as the GC does not look into
abstract/custom blocks, it will never result in the GC exploding because
a dangling pointer points into the GC heap.

MfG
        Goswin


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-03-03 11:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-01  3:55 How to pass C pointers to Caml Jianzhou Zhao
2010-03-01  6:22 ` [Caml-list] " Florent Monnier
2010-03-01 13:23   ` Jianzhou Zhao
2010-03-01 13:24   ` Goswin von Brederlow
2010-03-01 23:04     ` Florent Monnier
2010-03-02 10:19       ` Goswin von Brederlow
2010-03-02 11:34         ` Florent Monnier
2010-03-03 11:02           ` Goswin von Brederlow

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).