ffi/SDL problem in C

I don’t know if it’s a C, SDL or ffi error. The intention is to pass a functor containing both the surface and texture of an image.

static foreign_t loadImage(term_t t1, int n)
{
	char *s;
	void *p;
	PL_get_chars(t1,&s,CVT_STRING);
	printf("l;%s;\n",s);
	SDL_Surface* loadedSurface = IMG_Load( s ); //error here?
	term_t a1=PL_new_term_ref();term_t a2=PL_new_term_ref();
	term_t a;
	functor_t img=PL_new_functor(PL_new_atom("image"),2);
	PL_put_atom_chars(a1, "gnu");
	PL_put_integer(a2, 50);
	PL_cons_functor(a,img,a1,a2);
	PL_unify(t1+1,a);
	PL_succeed;
}

When I load an image, it works. Making a functor also works. If I have both the code for loading an image with IMG_Load and the functor at the same time, there’s an APPCRASH error.

:- use_foreign_library(foreign(lib)).
start :- init,%circlefill(0, 100, 5, 15),check(2),
	loadImage("hello.bmp",Y),write("fc;"),writeln(Y),
	%drawImage(Y,1,1),update,writeln(Y),sdl_delay,
	exit,halt.
swipl-ld -shared lib.c -o lib -IC:/*/i686-w64-mingw32/include/SDL2 -LC:/*/i686-w64-mingw32/lib -lSDL2 -lSDL2main -lSDL2_image 
swipl -f lib.pl -g start,halt

a is not initialized.

t1+1 doesn’t exist.

the second argument is of type term_t and is the second Prolog argument.

Unification may fail, use return PL_unify(t2, a);

In general, do not ignore the return values. almost all the interface functions may fail. The real crash is probably due to the uninitialized a.

Consider the C++ interface if you don’t like checking return values …

I’ve made some changes to the C++ interface (hopefully an improvement), which are awaiting review. ENHANCED: Version 2 of C++ interface by kamahen · Pull Request #16 · SWI-Prolog/packages-cpp · GitHub

Besides avoiding the need to check return codes in most place, the C++ interface initializes things and makes it easier to construct terms (and it does the PL_new_functor() for you). You can see an example of creating a term in PlResourceError() in SWI-cpp.h (the interface for constructing such a term has changed slightly between versions 1 and 2 of the C++ interface, but is still basically the same). If you can give me an example of the term you’re trying to construct, I can give you the C++ code to do that. (e.g., are you trying to construct image(gnu,50))?

BTW, instead of using printf() for debugging, you can use Sdprintf().

That solves the issue. I’ll keep in mind there’s a C++ interface.
BTW, I am using PL_pointer.
PL_put_pointer(a1, loadedSurface); PL_put_pointer(a2, newTexture);

the second argument is of type term_t and is the second Prolog argument.

I’m confused since the docs still use n.
https://eu.swi-prolog.org/pldoc/man?section=foreign-register-predicate

Probably “blobs” are a better interface than raw pointers; but they require a bit more work. I’m planning on a C++ interface to blobs, to make it easier to use them.

As for PL_register_foreign() et al, the 2nd argument is the arity: this determines the number of term_t arguments you need to put in your function. E.g., the “regex” foreign library has:

PL_register_foreign("re_compile, 3, re_match_, 0);

which corresponds to

static foreign_t
re_compile_(term_t pat, term_t reb, term_t options)
{ ...
}

(If you used the C++ interface, then you’d write PREDICATE(re_compile 3) and reference pat using A1, reb using A2, and options using A3.)