David,
My situation is slightly unusual so perhaps it's useful/interesting to
explain some background. I'm working on support for GLib/GTK in SML
which involves a significant number of calls to C functions. These C
functions need wrapping to provide a suitable ML interface for various
reasons. One such reason is for C string matters relating to optional
strings using null pointers, in place modification and allocation which
the caller must free. Given the number of C functions and the
requirement for implementation across different SML compilers, I am
creating a portable ML wrapping layer to reduce compiler-specific ML.
For C strings, there is a module which provides various wrapping
functions with a pointer-like abstract type cstring. It is this cstring
type that has a null value.
So, on the one hand, I can actually just remove val null from the
interface. A null cstring can be constructed via another function.
However, it seems natural to have a null value. On the other hand,
using vol option to implement a possibly-null pointer works (taking NONE
as null and SOME v as possibly-null). However, it seems perverse having
an ML datatype for nothing more than an actual C pointer.
Either way, a null pointer is going to create a new vol each time (as I
understand it) which involves a small amount of allocation. Perhaps a
persistent null : vol is worthwhile just from an efficiency perspective?
Regarding vol comparison, I actually meant comparison of the underlying
C pointers. This was only motivated by considering the implementation
of comparison with null, so probably not worth exploring.
Thanks,
Phil
On 15/11/11 15:30, David Matthews wrote:
Phil,
I think it could be possible to provide CInterface.null as a persistent
vol pointing to a value containing (void*)0. I know that seems a
contradiction but it should be possible. I'm just not sure it's
necessary. Why do you need to have "null" and "isNull"? Have you
considered instead building converters between the C data structure and
ML and doing everything within ML. There's example of this in
mlsource/extra/CInterface/Examples/ForeignTest.sml which converts a
simple tree structure:
(* Example of creating a conversion for a datatype. *)
datatype intTree = NullTree | Node of {left: intTree, right: intTree,
valu: int};
(* The corresponding C structure is
typedef struct _tree {
struct _tree *left, *right;
int nValue;
} *tree;
*)
On the your question about equality for vols: it's possible that there
could be an equality test but I'm not sure it would be very useful. All
it would do would test whether they were the same vol but that wouldn't
tell you whether two vols contained the same C data.
Regards,
David
On 13/11/2011 21:35, Phil Clayton wrote:
On 11/11/11 20:18, Phil Clayton wrote:
I am currently implementing
type t
val null : t
val isNull : t -> bool
where type t = CInterface.vol. There is no problem doing this but I
wondered whether I could improve the CInterface structure to avoid
annoying little C library functions.
I have realized that C functions are not necessary to implement these -
just to toClong and fromClong:
val null = toClong 0
fun isNull v = fromClong v = 0
Would it be at all controversial to include
null : vol
in CInterface?
For a different reason, this could still be useful. I had forgotten that
volatiles do not persist in saved states or executables (it should have
been obvious from the name) so I can't see how to create such a null
value to implement
val null : t
where type t = CInterface.vol. (There is nothing volatile about null
really.)
Perhaps the best approach here is to implement with type t =
CInterface.vol option, with NONE representing null.
Phil
_______________________________________________
polyml mailing list
polyml@inf.ed.ac.uk
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
_______________________________________________
polyml mailing list
polyml@inf.ed.ac.uk
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
_______________________________________________
polyml mailing list
polyml@inf.ed.ac.uk
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml