[m-users.] Calling type constructors from C

emacstheviking objitsu at gmail.com
Wed Jul 10 19:28:47 AEST 2019


Julien, thank you also for that reply. I have made those changes in my
module and it's working as I wanted it to.
@Zoltan Somogyi <zoltan.somogyi at runbox.com>  thank you too!

Sean.


On Wed, 10 Jul 2019 at 10:26, Julien Fischer <jfischer at opturion.com> wrote:

>
> Hi Sean,
>
> On Wed, 10 Jul 2019, emacstheviking wrote:
>
> > Any clues in the documentation as to where I can find out how to do
> > this? I've looked (and failed) to figure out how to call "maybe(T)"
>
> You don't call maybe(T), in this case you are attempting to construct
> it.
>
> > from C, basically I have the result of calling a C function that
> > reutns NULL or a window pointer:
> >    SDL_WIndow *w = SDL_CreateWindow(...);
> >
> > and I want the pred to return maybe(sdl_window) where so in my main code
> I can switch on the result blah blah
> >
> > sdl_creatwindow(..., MW, ..., !IO),
> > (
> >     MW = yes(Wnd),
> >     % start my app
> > ;
> >     MW = no,
> >     % fail path
> > ),
> >
> >
> > :- type sdl_window.
> > :- pragma foreign_type("C", sdl_window, "SDL_Window *",
> [can_pass_as_mercury_type]).
> >
> > It's just knowing what the "way" is?!?!
>
> The two usual approaches here would be:
>
> 1. Export a Mercury function to C that wraps the result of
> SDL_CreatWindow and call that from within the foreign_proc for
> sdl_createwindow.  E.g.
>
>     :- pragma foreign_export("C", maybe_yes_window(in) = out,
>         "MER_maybe_yes_window").
>     :- func maybe_yes_window(sdl_window) = maybe(sdl_window).
>     maybe_yes_window(W) = yes(W).
>
>     :- pragma foreign_export("C", maybe_no_window = out,
>        "MER_maybe_no_window").
>     :- func maybe_no_window = maybe(sdl_window).
>     maybe_no_window = no.
>
>     :- pragma foreign_proc("C",
>        sdl_createwindow(... MW::in, ... _IO0::di, IO::uo),
>        [will_call_mercury, promise_pure],
>     "
>        SDL_Window *w = <<create the window>>;
>        if (w == null) {
>           MW = MER_maybe_no_window();
>        } else {
>           MW = MER_maybe_yes_window(w);
>        }
>    ").
>
> NOTE: since sdl_createwindow will make calls back to Mercury the
> 'will_call_mercury' foreign code attribute must be set on the foreign
> proc.
>
> 2. Return an additional flag indicating if the window pointer is null or
> not.
>
>    sdl_createwindow(..., MW, ..., !IO) :-
>      do_createwindow(..., IsNull, W, !IO),
>      (
>           IsNull = no,
>           MW = yes(W)
>      ;
>           IsNull = yes,
>           MW = no
>      ).
>
>    :- pred do_createwindow(..., bool::out, sdl_window::out,
>      io::di, io::uo) is det.
>    :- pragma foreign_proc("C",
>        do_create_window(..., IsNull::out, W::out, _IO0::, _IO::uo),
>        [will_not_call_mercury, promise_pure],
>    "
>       W = <<create the window>>;
>       IsNull = (W == null) ? MR_YES : MR_NO;
>    ").
>
> Julien.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20190710/9a2dc8ed/attachment-0001.html>


More information about the users mailing list