[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