Обсуждение: PostgreSQL C Language Extension with C++ Code

Поиск
Список
Период
Сортировка

PostgreSQL C Language Extension with C++ Code

От
TalGloz
Дата:
Hi,

I've searched information about my problem in the archives and on the
internet, but it didn't help. I have this small myfunc.cpp

1:   #include <postgres.h>
2:   #include <utils/rel.h>
3:   #include <postgres.h>
4:   #include <fmgr.h>
5:   #include <utils/array.h>
6:   #include <utils/builtins.h>
7:   #include <catalog/pg_type.h>
8:   #include <string>
9:   #include <vector>
10: #include <stdlib.h>
11: #include <stdint.h>
12: #include <iostream>
13: #include <fstream>
14: #include <seal/seal.h> // external compiled c++ library linked on
running 'make'
15:
16: #ifdef PG_MODULE_MAGIC
17: PG_MODULE_MAGIC;
18: #endif
19: 
20: Datum sum_of_numbers(PG_FUNCTION_ARGS);
21: PG_FUNCTION_INFO_V1(sum_of_numbers);
22: 
23: extern "C" {
24:         int64_t sum_of_numbers(){
25:                 std::vector<int64_t> numbers {23, 445, 64};
26:                 auto sum = 0;
27:                 for (auto &item : numbers){
28:                         sum += item;
29:                 }
30:                 return sum;
31:         }
32: }

And I compile without any problem suing this Makefiles:

1:   MODULES = myfunc
2: 
3:   PG_CONFIG = /usr/pgsql-10/bin/pg_config
4:   PGXS = $(shell $(PG_CONFIG) --pgxs)
5:   INCLUDEDIR = $(shell $(PG_CONFIG) --includedir-server)
6:   INCLUDE_SEAL = /usr/local/include/seal
7:   INCLUDE_SEAL_LIB = /usr/local/lib/libseal.a
8:   INCLUDE_CPPCODEC = /usr/local/include/cppcodec
9:   #CFLAGS = -std=c11
10: #CFLAGS = --std=c++14 -fPIC -Wall -Werror -g3 -O0
11: include $(PGXS)
12: myfunc.so: myfunc.o
13:         g++ -shared -o myfunc.so myfunc.o
14: 
16: myfunc.o: myfunc.cpp
17:        g++ --std=c++17 -fPIC -Wall -Werror -g3 -O0 -o myfunc.o -c
myfunc.cpp -I$(INCLUDEDIR) -L$(INCLUDE_SEAL_LIB) -I$(INCLUDE_SEAL)
-I$(INCLUDE_CPPCODEC)
18: 

After copying the myfunc.so file to the PostgreSQL lib folder and executing:

1: CREATE OR REPLACE FUNCTION 
2:    sum_of_numbers() RETURNS integer AS 'myfunc' 
3: LANGUAGE C STRICT;

I get this error:
*ERROR:  incompatible library "/usr/pgsql-10/lib/myfunc.so": missing magic
block
HINT:  Extension libraries are required to use the PG_MODULE_MAGIC macro.
SQL state: XX000*

I've added the files and line numbers for an easier discussion.

Thanks a lot,
Tal

myfunc.cpp <http://www.postgresql-archive.org/file/t351748/myfunc.cpp>  
Makefiles.Makefiles
<http://www.postgresql-archive.org/file/t351748/Makefiles.Makefiles>  



--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html


Re: PostgreSQL C Language Extension with C++ Code

От
Tom Lane
Дата:
TalGloz <glozmantal@gmail.com> writes:
> I've searched information about my problem in the archives and on the
> internet, but it didn't help. I have this small myfunc.cpp
> [ that doesn't work ]

> 16: #ifdef PG_MODULE_MAGIC
> 17: PG_MODULE_MAGIC;
> 18: #endif

Hmm ... don't use an #ifdef there.  If you don't have the macro defined,
you want to fail, not silently build an extension without it.

It's possible you need extern "C" { ... } around the macro, too.

            regards, tom lane


Re: PostgreSQL C Language Extension with C++ Code

От
Igor Korot
Дата:
Hi,

On Sun, Aug 12, 2018 at 12:05 PM, TalGloz <glozmantal@gmail.com> wrote:
> Hi,
>
> I've searched information about my problem in the archives and on the
> internet, but it didn't help. I have this small myfunc.cpp
>
> 1:   #include <postgres.h>
> 2:   #include <utils/rel.h>
> 3:   #include <postgres.h>
> 4:   #include <fmgr.h>
> 5:   #include <utils/array.h>
> 6:   #include <utils/builtins.h>
> 7:   #include <catalog/pg_type.h>
> 8:   #include <string>
> 9:   #include <vector>
> 10: #include <stdlib.h>
> 11: #include <stdint.h>
> 12: #include <iostream>
> 13: #include <fstream>
> 14: #include <seal/seal.h> // external compiled c++ library linked on
> running 'make'
> 15:
> 16: #ifdef PG_MODULE_MAGIC

I think you're missing  "n" here.
Should be:

#ifndef PG_MODULE_MAGIC

.

Thank you.

> 17: PG_MODULE_MAGIC;
> 18: #endif
> 19:
> 20: Datum sum_of_numbers(PG_FUNCTION_ARGS);
> 21: PG_FUNCTION_INFO_V1(sum_of_numbers);
> 22:
> 23: extern "C" {
> 24:         int64_t sum_of_numbers(){
> 25:                 std::vector<int64_t> numbers {23, 445, 64};
> 26:                 auto sum = 0;
> 27:                 for (auto &item : numbers){
> 28:                         sum += item;
> 29:                 }
> 30:                 return sum;
> 31:         }
> 32: }
>
> And I compile without any problem suing this Makefiles:
>
> 1:   MODULES = myfunc
> 2:
> 3:   PG_CONFIG = /usr/pgsql-10/bin/pg_config
> 4:   PGXS = $(shell $(PG_CONFIG) --pgxs)
> 5:   INCLUDEDIR = $(shell $(PG_CONFIG) --includedir-server)
> 6:   INCLUDE_SEAL = /usr/local/include/seal
> 7:   INCLUDE_SEAL_LIB = /usr/local/lib/libseal.a
> 8:   INCLUDE_CPPCODEC = /usr/local/include/cppcodec
> 9:   #CFLAGS = -std=c11
> 10: #CFLAGS = --std=c++14 -fPIC -Wall -Werror -g3 -O0
> 11: include $(PGXS)
> 12: myfunc.so: myfunc.o
> 13:         g++ -shared -o myfunc.so myfunc.o
> 14:
> 16: myfunc.o: myfunc.cpp
> 17:        g++ --std=c++17 -fPIC -Wall -Werror -g3 -O0 -o myfunc.o -c
> myfunc.cpp -I$(INCLUDEDIR) -L$(INCLUDE_SEAL_LIB) -I$(INCLUDE_SEAL)
> -I$(INCLUDE_CPPCODEC)
> 18:
>
> After copying the myfunc.so file to the PostgreSQL lib folder and executing:
>
> 1: CREATE OR REPLACE FUNCTION
> 2:    sum_of_numbers() RETURNS integer AS 'myfunc'
> 3: LANGUAGE C STRICT;
>
> I get this error:
> *ERROR:  incompatible library "/usr/pgsql-10/lib/myfunc.so": missing magic
> block
> HINT:  Extension libraries are required to use the PG_MODULE_MAGIC macro.
> SQL state: XX000*
>
> I've added the files and line numbers for an easier discussion.
>
> Thanks a lot,
> Tal
>
> myfunc.cpp <http://www.postgresql-archive.org/file/t351748/myfunc.cpp>
> Makefiles.Makefiles
> <http://www.postgresql-archive.org/file/t351748/Makefiles.Makefiles>
>
>
>
> --
> Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html
>


Re: PostgreSQL C Language Extension with C++ Code

От
TalGloz
Дата:
OK now I have this code:

1:   extern "C" {  // The C header should go here
2:   #include <postgres.h>
3:   #include <utils/rel.h>
4:   #include <fmgr.h>
5:   #include <utils/array.h>
6:   #include <utils/builtins.h>
7:   #include <catalog/pg_type.h>
8:   #include <stdlib.h>
9:   #include <stdint.h>
10:  
11: PG_MODULE_MAGIC;
12: }
13:
14: // CPP header without extern "C"
15: #include <string>
16: #include <vector>
17: #include <iostream>
18: #include <fstream>
19: #include <seal/seal.h> // external compiled c++ library linked on
running 'make'
20:
21: Datum sum_of_numbers(PG_FUNCTION_ARGS);
22: PG_FUNCTION_INFO_V1(sum_of_numbers);
33: 
34: extern "C" { // CPP function
35:         int64_t sum_of_numbers(){
36:                 std::vector<int64_t> numbers {23, 445, 64};
37:                 auto sum = 0;
38:                 for (auto &item : numbers){
39:                         sum += item;
40:                 }
41:                 return sum;
42:         }
43: }

The error this time for PostgreSQL is:
*ERROR:  could not find function information for function "sum_of_numbers"
HINT:  SQL-callable functions need an accompanying
PG_FUNCTION_INFO_V1(funcname).
SQL state: 42883*

Thanks,
Tal




--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html


Re: PostgreSQL C Language Extension with C++ Code

От
Tom Lane
Дата:
TalGloz <glozmantal@gmail.com> writes:
> The error this time for PostgreSQL is:
> *ERROR:  could not find function information for function "sum_of_numbers"
> HINT:  SQL-callable functions need an accompanying
> PG_FUNCTION_INFO_V1(funcname).
> SQL state: 42883*

Probably need extern "C" around the PG_FUNCTION_INFO_V1 macro, too.
Both those macros produce C function definitions under the hood,
and said functions need to not be name-mangled by C++.

            regards, tom lane


Re: PostgreSQL C Language Extension with C++ Code

От
TalGloz
Дата:
I did it with the macros

extern "C" {
Datum sum_of_numbers(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(sum_of_numbers);
}

But now my compiler throws some other errors when running make:

g++ --std=c++17 -fPIC -Wall -Werror -g3 -O0 -o myfunc.o -c myfunc.cpp
-I/usr/pgsql-10/include/server -L"/usr/local/lib/libseal.a"
-I"/usr/local/include/seal" -I"/usr/local/include/cppcodec"
myfunc.cpp:29:10: error: conflicting declaration of C function ‘int64_t
sum_of_numbers()’
  int64_t sum_of_numbers(){
          ^~~~~~~~~~~~~~
In file included from /usr/pgsql-10/include/server/utils/array.h:64,
                 from /usr/pgsql-10/include/server/utils/acl.h:38,
                 from
/usr/pgsql-10/include/server/catalog/objectaddress.h:18,
                 from
/usr/pgsql-10/include/server/catalog/pg_publication.h:21,
                 from /usr/pgsql-10/include/server/utils/rel.h:21,
                 from myfunc.cpp:3:
myfunc.cpp:25:21: note: previous declaration ‘Datum
sum_of_numbers(FunctionCallInfo)’
 PG_FUNCTION_INFO_V1(sum_of_numbers);
                     ^~~~~~~~~~~~~~
/usr/pgsql-10/include/server/fmgr.h:374:14: note: in definition of macro
‘PG_FUNCTION_INFO_V1’
 extern Datum funcname(PG_FUNCTION_ARGS); \
              ^~~~~~~~
make: *** [Makefile:16: myfunc.o] Error 1

Why is it so hard to use C++ with PostgerSQL for a C extension? :)

Regards,
Tal



--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html


Re: PostgreSQL C Language Extension with C++ Code

От
Dmitry Igrishin
Дата:
вс, 12 авг. 2018 г. в 21:40, TalGloz <glozmantal@gmail.com>:
>
> I did it with the macros
>
> extern "C" {
> Datum sum_of_numbers(PG_FUNCTION_ARGS);
> PG_FUNCTION_INFO_V1(sum_of_numbers);
> }
>
> But now my compiler throws some other errors when running make:
>
> g++ --std=c++17 -fPIC -Wall -Werror -g3 -O0 -o myfunc.o -c myfunc.cpp
> -I/usr/pgsql-10/include/server -L"/usr/local/lib/libseal.a"
> -I"/usr/local/include/seal" -I"/usr/local/include/cppcodec"
> myfunc.cpp:29:10: error: conflicting declaration of C function ‘int64_t
> sum_of_numbers()’
>   int64_t sum_of_numbers(){
>           ^~~~~~~~~~~~~~
> In file included from /usr/pgsql-10/include/server/utils/array.h:64,
>                  from /usr/pgsql-10/include/server/utils/acl.h:38,
>                  from
> /usr/pgsql-10/include/server/catalog/objectaddress.h:18,
>                  from
> /usr/pgsql-10/include/server/catalog/pg_publication.h:21,
>                  from /usr/pgsql-10/include/server/utils/rel.h:21,
>                  from myfunc.cpp:3:
> myfunc.cpp:25:21: note: previous declaration ‘Datum
> sum_of_numbers(FunctionCallInfo)’
>  PG_FUNCTION_INFO_V1(sum_of_numbers);
>                      ^~~~~~~~~~~~~~
> /usr/pgsql-10/include/server/fmgr.h:374:14: note: in definition of macro
> ‘PG_FUNCTION_INFO_V1’
>  extern Datum funcname(PG_FUNCTION_ARGS); \
>               ^~~~~~~~
> make: *** [Makefile:16: myfunc.o] Error 1
>
> Why is it so hard to use C++ with PostgerSQL for a C extension? :)
It is not.


Re: PostgreSQL C Language Extension with C++ Code

От
Tom Lane
Дата:
TalGloz <glozmantal@gmail.com> writes:
> But now my compiler throws some other errors when running make:

> myfunc.cpp:29:10: error: conflicting declaration of C function ‘int64_t
> sum_of_numbers()’
>   int64_t sum_of_numbers(){
>           ^~~~~~~~~~~~~~

Well, yeah, you forgot to repeat the argument list here.  For that
matter, spelling Datum as int64_t is a recipe for trouble, even if
it works on some particular platform.  Should be

Datum sum_of_numbers(PG_FUNCTION_ARGS) { ...

> Why is it so hard to use C++ with PostgerSQL for a C extension? :)

Probably because you've failed to break your bad C++ habits.

            regards, tom lane


Re: PostgreSQL C Language Extension with C++ Code

От
TalGloz
Дата:
Let me see if I understood you correctly. I cant have a code like this:

extern "C" {
        int sum_of_numbers(){
                std::vector<int> numbers {23, 445, 64};
                int sum = 0;
                for (auto &item : numbers){
                        sum += item;
                }
                return sum;
        }
}

And I have to declare my function with inside the 
Datum sum_of_numbers(PG_FUNCTION_ARGS){
        // function code here
}

Sorry for the log mails. I'm having problems to understand, how to change
the construction of myfunc.cpp to run the code. 



--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html


Re: PostgreSQL C Language Extension with C++ Code

От
TalGloz
Дата:
OK It worked. This is how I did it, hopefully it is right

extern "C" {
#include <postgres.h>
#include <utils/rel.h>
#include <fmgr.h>
#include <utils/array.h>
#include <utils/builtins.h>
#include <catalog/pg_type.h>
#include <stdlib.h>
#include <stdint.h>

PG_MODULE_MAGIC;
}

#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <seal/seal.h> // external compiled c++ library linked on running
'make'


extern "C" {
Datum sum_of_numbers(PG_FUNCTION_ARGS){
        std::vector<int> numbers {23, 445, 64};
                int sum = 0;
                for (auto &item : numbers){
                        sum += item;
                }
                return sum;
};
PG_FUNCTION_INFO_V1(sum_of_numbers);
}

I've managed to create and execute the function in my PostgreSQL database.

So basically I can execute any CPP code as long as I declare my functions
like this:

extern "C" {
    Datum function_name(PG_FUNCTION_ARGS){
         // CPP code here
    };

    PG_FUNCTION_INFO_V1(function_name);
}

In addition tho thath, all the C headers should be * inside a extern "C" {
}* block and all the CPP headers *outside the extern "C" { }* block, did I
get it right? 

Thanks,
Tal



--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html