Thread: Help with adding C-Language Functions
Hi, I am trying to add a C-Language Function. I have created a small example in file BlackboardFunctions.c. #include <postgres.h> #include <fmgr.h> PG_FUNCTION_INFO_V1(add_one); Datum add_one(PG_FUNCTION_ARGS) { int32 arg = PG_GETARG_INT32(0); PG_RETURN_INT32(arg + 1); } The make file: make: cc -fpic -c BlackboardFunctions.c -I /home/grads/carrolls/source/postgresql-7.4.5/src/include/ cc -shared-o BlackboardFunctions.so BlackboardFunctions.o Everything compiles nicely and when i try to add the function using: Blackboard=# CREATE FUNCTION add_one(integer) RETURNS integer Blackboard-# AS '/home/grads/carrolls/gradstudies/implementation/BlackboardFunctions/BlackboardFunctions', 'add_one' Blackboard-# LANGUAGE C STRICT; I get the following error: ERROR: could not find function "add_one" in file "/home/grads/carrolls/gradstudies/implementation/BlackboardFunctions/BlackboardFunctions.so" A grep of BlackboardFunction.so finds add_one. I figure i must be doing something obviously wrong but for the life of me i cant figure out what that might bt. Can anyone recommend a course of action? Thank you, Seamus
I changed my file from BlackboardFunctions.c to all lowercase, blackboardfunctions.c, and the database now finds the add_one function. Crazy. Can someone explain the reason why this happened? Is this a linker issue or something in postgresql. Seamus On Wed, 9 Feb 2005, Seamus Thomas Carroll wrote: > Hi, > > I am trying to add a C-Language Function. I have created a small example in > file BlackboardFunctions.c. > > #include <postgres.h> > #include <fmgr.h> > > PG_FUNCTION_INFO_V1(add_one); > > Datum > add_one(PG_FUNCTION_ARGS) > { > int32 arg = PG_GETARG_INT32(0); > > PG_RETURN_INT32(arg + 1); > } > > The make file: > make: > cc -fpic -c BlackboardFunctions.c -I > /home/grads/carrolls/source/postgresql-7.4.5/src/include/ > cc -shared -o BlackboardFunctions.so BlackboardFunctions.o > > Everything compiles nicely and when i try to add the function using: > Blackboard=# CREATE FUNCTION add_one(integer) RETURNS integer > Blackboard-# AS > '/home/grads/carrolls/gradstudies/implementation/BlackboardFunctions/BlackboardFunctions', > 'add_one' > Blackboard-# LANGUAGE C STRICT; > > I get the following error: > ERROR: could not find function "add_one" in file > "/home/grads/carrolls/gradstudies/implementation/BlackboardFunctions/BlackboardFunctions.so" > > A grep of BlackboardFunction.so finds add_one. > I figure i must be doing something obviously wrong but for the life of me i > cant figure out what that might bt. Can anyone recommend a course of action? > > Thank you, > > Seamus > > ---------------------------(end of broadcast)--------------------------- > TIP 3: if posting/reading through Usenet, please send an appropriate > subscribe-nomail command to majordomo@postgresql.org so that your > message can get through to the mailing list cleanly >
On Thu, Feb 10, 2005 at 01:17:14AM -0700, Seamus Thomas Carroll wrote: > I changed my file from BlackboardFunctions.c to all lowercase, > blackboardfunctions.c, and the database now finds the add_one function. > > Crazy. Can someone explain the reason why this happened? Is this a > linker issue or something in postgresql. What platform are you using? I built and loaded your original example with mixed-case file names on FreeBSD and Solaris and had no problems. -- Michael Fuhr http://www.fuhr.org/~mfuhr/
Seamus Thomas Carroll <carrolls@cpsc.ucalgary.ca> writes: > I changed my file from BlackboardFunctions.c to all lowercase, > blackboardfunctions.c, and the database now finds the add_one function. I'm betting that the actual sequence of events was more like this: CREATE FUNCTION f1(...) as '/home/.../BlackboardFunctions' ...;[ test f1, it works, cool ][ add add_one to C source file,recompile ]CREATE FUNCTION add_one(...) as '/home/.../BlackboardFunctions' ...;[ fails ][ rename file ]CREATE FUNCTIONadd_one(...) as '/home/.../blackboardfunctions' ...;[ works ] The reason the second try didn't work is that an existing backend will not re-load an already loaded .so file, unless you force it to with the LOAD command. It doesn't notice that you've modified the file. Had you started a fresh session, things would have worked, too. regards, tom lane
Thinking back I think i tried g++ first which caused the error to occur. When i then tried cc the .so was already loaded. I have c++ classes i want to use but when i complile using g++ i get the error (cant find function x in file.so). Does anyone have experience compiling c++ and loading the function? Seamus On Thu, 10 Feb 2005, Tom Lane wrote: > Seamus Thomas Carroll <carrolls@cpsc.ucalgary.ca> writes: >> I changed my file from BlackboardFunctions.c to all lowercase, >> blackboardfunctions.c, and the database now finds the add_one function. > > I'm betting that the actual sequence of events was more like this: > > CREATE FUNCTION f1(...) as '/home/.../BlackboardFunctions' ...; > [ test f1, it works, cool ] > [ add add_one to C source file, recompile ] > CREATE FUNCTION add_one(...) as '/home/.../BlackboardFunctions' ...; > [ fails ] > [ rename file ] > CREATE FUNCTION add_one(...) as '/home/.../blackboardfunctions' ...; > [ works ] > > The reason the second try didn't work is that an existing backend will > not re-load an already loaded .so file, unless you force it to with the > LOAD command. It doesn't notice that you've modified the file. Had you > started a fresh session, things would have worked, too. > > regards, tom lane >
Seamus Thomas Carroll <carrolls@cpsc.ucalgary.ca> writes: > I have c++ classes i want to use but when i complile using g++ i get the > error (cant find function x in file.so). Does anyone have experience > compiling c++ and loading the function? The immediate problem is that you didn't declare the function as extern "C" so it doesn't follow C naming conventions. In general, though, it's fairly difficult to use any interesting C++ capabilities in a Postgres backend module, because the main backend does not contain the C++ library. So, for instance, I'd not expect C++ exceptions or RTTI to work at all well. regards, tom lane
Hi Tom, I am trying to LOAD the .so file and i have replaced the add_one function( this one compiled and tested after adding the extern "C"{}) with the concat_text function. It compiles but when i try the LOAD command i get the following error: ERROR: could not load library "/home/grads/.../BlackboardFunctions.so": /home/grads/.../BlackboardFunctions.so: undefined symbol: _Z16pg_detoast_datumP7varlena I am guessing this has something to do with the varlena in c.h. Seamus On Thu, 10 Feb 2005, Tom Lane wrote: > Seamus Thomas Carroll <carrolls@cpsc.ucalgary.ca> writes: >> I have c++ classes i want to use but when i complile using g++ i get the >> error (cant find function x in file.so). Does anyone have experience >> compiling c++ and loading the function? > > The immediate problem is that you didn't declare the function as extern > "C" so it doesn't follow C naming conventions. In general, though, it's > fairly difficult to use any interesting C++ capabilities in a Postgres > backend module, because the main backend does not contain the C++ > library. So, for instance, I'd not expect C++ exceptions or RTTI to > work at all well. > > regards, tom lane >
Seamus Thomas Carroll <carrolls@cpsc.ucalgary.ca> writes: > It compiles but when i try the LOAD command i get the following error: > ERROR: could not load library "/home/grads/.../BlackboardFunctions.so": > /home/grads/.../BlackboardFunctions.so: undefined symbol: _Z16pg_detoast_datumP7varlena extern "C" { ... } around all the Postgres include files, too, no doubt. You might wish to go and read some information about connecting C and C++, since you've obviously never done it before ;-) regards, tom lane