
Jan Wielemaker wrote:
Anyway for the others, I added
PL_action(PL_GMP_SET_ALLOC_FUNCTIONS, TRUE)
if you want Prolog's GMP allocation initialised *now* (without initializing the rest of SWI-Prolog). or
PL_action(PL_GMP_SET_ALLOC_FUNCTIONS, FALSE)
If you want to stop Prolog from setting the allocation functions. Must be called before PL_initialise(), of course.
I see how to use that in the foreign-calls-Prolog case. How can I achieve that in the Prolog-calls-foreign case (which is the one I am mostly interested in)?
You mean you load a shared object into Prolog? Good!
No, I am having problems with libraries statically linked to the SWI-Prolog system. These libraries (written in C++) use several statically allocated GMP numbers. When the system starts, the statically allocated variables are initialized with the GMP's memory allocation function. Then SWI-Prolog is given control and the allocation functions are changed. Then the system exits and the statically allocated variables are destroyed with the wrong (i.e., SWI-Prolog's) allocation function: which results into a segmentation fault. This change you have made to SWI-Prolog is really breaking everything here.
I'm not getting it. I think there are two situations: you embed Prolog, so you call PL_initialise() and you can call the PL_action(PL_GMP_SET_ALLOC_FUNCTIONS, FALSE) before it or you keep the Prolog toplevel and you load your code as a .so file into Prolog. I think both work fine, even with global C++ initializers. What am I missing?
Probably the fact that the constructors of global variables are all run (in unspecified order) before main() is given control. You can compile the following with
g++ -W -Wall test.cc
and see.
#include <iostream>
class Foo { public: Foo() { std::cout << "Foo::Foo() called." << std::endl; } };
Foo foo;
int main() { // Calling PL_action(PL_GMP_SET_ALLOC_FUNCTIONS, FALSE) here would not help. std::cout << "main() called." << std::endl; }
Of course, in the real code we have mpz_class, mpq_class and so forth instead of Foo. All the best,
Roberto