C++ foreign interface error

It was working before but oddly it isn’t. I don’t remember what version I was using when it worked. I’d appreciate any ideas on solving the issue.

I get the same ‘undefined reference’ error as below.

C:\Users\Computer\comp\sdl_pl-main>swipl-ld -shared test.cpp -o sdl
test.bat : c:/mingw/bin/…/lib/gcc/mingw32/9.2.0/…/…/…/…/mingw32/bin/ld.exe: test.ob
rC1EPKcS1_iPFjjiP20__PL_foreign_contextE]+0x2d): undefined reference to `PL_register_for

I updated to swi9 just to see what happens,

The code that uses PL_foreign_in_module() hasn’t changed in a long time.

I don’t use Windows, but from the error message, it appears that the message refers to the “mangled” form of the name (C++ “mangles” function names with extra information about the type, to allow overloading etc). This shouldn’t happen if your definition of PL_foreign_in_module() is inside a extern "C" { ... } block - which is what SWI-Prolog.h has. Perhaps you have either an ancient version of SWI-Prolog.h or a copy that has removed the extern "C"? (Unlikely that it’s ancient: the extern "C" was added 28 years ago.)

As to the second error, it looks strange. It’s using the “version 1” API (SWI-cpp.h), which hasn’t changed in almost a year: History for SWI-cpp.h - SWI-Prolog/packages-cpp · GitHub

It might help if you can give the result of swipl --version and your source code.

PS C:\Users\Computer> swipl --version
SWI-Prolog version 8.5.13 for x64-win64

(This version gives the first error, the second happens if I use the latest v9. g++ says version 9.2.0?)

#include <SWI-cpp.h>

PREDICATE (check,2) {

The most likely reason for those errors is a corrupted SWI-Prolog.h file. Version 8.5.13 is over a year old, so you might want to update to the latest (8.5.20 or 9.1.15) and verify your SWI-Prolog.h. It’s also possible that you have a bad SWI-Prolog.h in your include path – you can check this by deliberately putting a syntax error in the file you think is being included and see if you get a compile error.

(I’m sorry I can’t help more – I wrote SWI-cpp2.h but I use Linux, not Windows.)

BTW, you can see the name mangling:

$ c++filt
PlRegister::PlRegister(char const*, char const*, int, unsigned int (*)(unsigned int, int, __PL_foreign_context*))

Your little test program worked fine for me with gcc 13.2.0, but it should give the same result with earlier versions because, as far as I know, the object file formats and name-mangling haven’t changed:

$ cat ttt.cpp
#include <SWI-cpp.h>

PREDICATE (check,2) {
$ swipl-ld -shared ttt.cpp -o ttt.so
$ file ttt.so
ttt.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f7a95c7ea89fd036b08d82e21a5fed969c733b62, not stripped
$ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 9.1.15-2-ge5af93f95-DIRTY)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- use_foreign_library(ttt).

?- check(A,B).


% halt

It was a Windows-specific problem to do with Mingw, solved by using MSYS2.

If there’s information missing from the page for building with Windows, please add it here or submit a change, so that others don’t run into the problems you experienced.