[MLton-user] NLFFI: What is the correct way to convert C values to ML?

Matthew Fluet matthew.fluet at gmail.com
Tue Mar 1 07:26:52 PST 2011


Ivan,

On Tue, Mar 1, 2011 at 12:35 AM, Ivan Tomac <ivan.tomac at gmail.com> wrote:
> MLRep structure appears to be the safest bet however it is not compatible
> with that of SML/NJ which makes me wonder if it is meant to be an internal
> structure, not really exposed. But if that was the case, then why is it
> exposed?
> Should the MLRep structures in MLton and SML/NJ versions of NLFFI lib be
> updated to be compatible?
>
> Only other option I can think of is to use types like int32_t on the C side
> and Int32.toInt on the SML side, avoiding C int-s.
>
> So what is the correct way to convert a C int to an ML int?

It would help to know a little more about exactly where your C int is
coming from to know the best way to convert it to an ML int.

The differences between the MLRep structures in MLton and SML/NJ are a
documented design decision:
  http://mlton.org/MLNLFFIImplementation
  http://mlton.org/pipermail/mlton-user/2007-February/001025.html
I believe that the fine-grained C types better document an interface,
even if the underlying SML implementation needs to coerce small sized
values to larger sized values.

You are meant to use MLRep.Int.Signed.toInt and
MLRep.Int.Signed.fromInt to convert a C int to and from an SML Int.int
(when using NLFFI generated code).  Of course, those conversions could
fail due to Overflow if the C int size and the SML Int.int size
differ.  But, note that the
MLRep.{Char,Short,Int,Long,LongLong}.Signed structures match the
INTEGER signature and the
MLRep.{Char,Short,Int,Long,LongLong}.Unsigned structures match the
WORD signature, so, often if one is doing simple arithmetic on these
values, there isn't a need to explicitly convert it to an SML Int.int.

If you are using NLFFI, my best suggestion is to introduce a
compatibility structure.  For your MLton code, you just need the
following:

mlton-mlrep.sml:
structure ZMLRep = MLRep

For your SML/NJ code, you just need the following:

smlnj-mlrep.sml:
structure ZMLRep = struct
  structure Char = struct
    structure Signed = MLRep.Signed
    structure Unsigned = MLRep.Unsigned
    structure SignedBitops = MLRep.SignedBitops
  end
  structure Short = struct
    structure Signed = MLRep.Signed
    structure Unsigned = MLRep.Unsigned
    structure SignedBitops = MLRep.SignedBitops
  end
  structure Int = struct
    structure Signed = MLRep.Signed
    structure Unsigned = MLRep.Unsigned
    structure SignedBitops = MLRep.SignedBitops
  end
  structure Long = struct
    structure Signed = MLRep.Signed
    structure Unsigned = MLRep.Unsigned
    structure SignedBitops = MLRep.SignedBitops
  end
  structure LongLong = struct
    structure Signed = MLRep.LongLongSigned
    structure Unsigned = MLRep.LongLongUnsigned
    (* structure SignedBitops = MLRep.LongLongSignedBitops *)
  end
  structure Float = MLRep.Real
  structure Double = MLRep.Real
end

Now, if you use ZMLRep structures to manipulate the C data, you should
have code that works with both SML/NJ and MLton.

Let me know if the above works.  I believe that it should, and it is
an innocuous enough extension of SML/NJ's existing MLRep structure
that we could probably get it added to the SML/NJ version of the NLFFI
Library.



More information about the MLton-user mailing list