Creation of extensions and Backend C/C++ functions.

From: PG Doc comments form <noreply(at)postgresql(dot)org>
To: pgsql-docs(at)lists(dot)postgresql(dot)org
Cc: tconorkerrigan(at)gmail(dot)com
Subject: Creation of extensions and Backend C/C++ functions.
Date: 2024-11-25 16:11:38
Message-ID: 173255109822.2092749.3336245972313402414@wrigleys.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-docs

The following documentation comment has been logged on the website:

Page: https://www.postgresql.org/docs/17/xfunc-c.html
Description:

I can and have implemented triivial C/C++ functions to compile and link to
Postgres. An example follows:-

#include "postgres.h"
#include "fmgr.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

/* Function declaration */
PG_FUNCTION_INFO_V1(always_true);

/* The function alwaysTrue() - returns true */
Datum
always_true(PG_FUNCTION_ARGS)
{
PG_RETURN_BOOL(true);
}

PG_FUNCTION_INFO_V1(is_WIN32);
Datum
is_WIN32(PG_FUNCTION_ARGS)
{
bool result = false;
#ifdef WIN32
result = true;
#endif
PG_RETURN_BOOL(result);
}
This compiles and is linked as follows:-
cc -fPIC -IC:/msys64/mingw64/include/POSTGR~1/server -shared -o ext.dll *.c
-I/mingw64/include/POSTGR~1
cp ext.dll C:/msys64/mingw64/lib/POSTGR~1/.
(from pg_config --pkglibdir
C:/msys64/mingw64/lib/POSTGR~1)
I use pgAdmin to create or replace functions .... They work correctly.

The problem I have arises when I try to add a non trivial function for my
app. The function is :-
PG_FUNCTION_INFO_V1(set_balance_with_id);
Datum set_balance_with_id(PG_FUNCTION_ARGS) {
int32 arg0 = PG_GETARG_INT32(0);
bool arg1 = PG_GETARG_BOOL(1);
bool result = set_balance_with_id_cpp (arg0, arg1, 0.00f);
PG_RETURN_BOOL(result);
}
The function set_balance_with_id_cpp is defined in a wrapper thus:-
#include "LedgerOrAccount.h"
#include "LedgerOrAccountWrapper.h"

#include <iostream>

// Define the C-compatible wrapper functions
// Implement the C-compatible wrapper functions
//extern "C" {


// Define the C++ wrapper function for PostgreSQL
bool set_balance_with_id_cpp(int id, bool debit, double balance) {
double new_balance = 0.00f;
try {
// Create an instance of the LedgerOrAccount class
LedgerOrAccount ledger(id);
TransactionType transactionType = debit? DEBIT: CREDIT;

// Call the setBalance method on the class
new_balance = ledger.setBalance(balance, transactionType);
} catch (const std::exception& e) {
std::cerr << "set_balance_with_id_cpp -> " << e.what() <<
std::endl;
}

// Return true if balance is set successfully
return (new_balance >= 0.00f);
}
Now I can compile the function into a shared library but when I try to load
it, postgres cannot do so. pgAdmin:->
DEBUG: StartTransaction(1) name: unnamed; blockState: DEFAULT; state:
INPROGRESS, xid/subid/cid: 0/1/0
LOG: statement: LOAD 'my_extension';

DEBUG: find_in_dynamic_libpath: trying "C:/Program
Files/PostgreSQL/17/lib/my_extension"
DEBUG: mapped win32 error code 2 to 2
DEBUG: mapped win32 error code 2 to 2
DEBUG: find_in_dynamic_libpath: trying
"C:/msys64/mingw64/lib/POSTGR~1/my_extension"
DEBUG: mapped win32 error code 2 to 2
DEBUG: mapped win32 error code 2 to 2
DEBUG: find_in_dynamic_libpath: trying
"C:/mysys64/mingw64/lib/my_extension"
DEBUG: mapped win32 error code 3 to 2
DEBUG: mapped win32 error code 3 to 2
DEBUG: find_in_dynamic_libpath: trying "C:/Program
Files/PostgreSQL/17/lib/my_extension.dll"
DEBUG: mapped win32 error code 2 to 2
DEBUG: mapped win32 error code 2 to 2
DEBUG: find_in_dynamic_libpath: trying
"C:/msys64/mingw64/lib/POSTGR~1/my_extension.dll"

ERROR: could not load library
"C:/msys64/mingw64/lib/POSTGR~1/my_extension.dll": The specified module
could not be found.

SQL state: 58P01
And in pgAdmin :-
-- Load the shared library if not already loaded
CREATE FUNCTION set_balance_with_id(int, double precision, boolean)
RETURNS boolean
AS 'my_extension', 'set_balance_with_id'
LANGUAGE c STRICT;

and identically, pgAdmin ->
DEBUG: StartTransaction(1) name: unnamed; blockState: DEFAULT; state:
INPROGRESS, xid/subid/cid: 0/1/0
LOG: statement: -- Load the shared library if not already loaded
CREATE FUNCTION set_balance_with_id(int, double precision, boolean)
RETURNS boolean
AS 'my_extension', 'set_balance_with_id'
LANGUAGE c STRICT;
DEBUG: find_in_dynamic_libpath: trying "C:/Program
Files/PostgreSQL/17/lib/my_extension"
DEBUG: mapped win32 error code 2 to 2
DEBUG: mapped win32 error code 2 to 2
DEBUG: find_in_dynamic_libpath: trying
"C:/msys64/mingw64/lib/POSTGR~1/my_extension"
DEBUG: mapped win32 error code 2 to 2
DEBUG: mapped win32 error code 2 to 2
DEBUG: find_in_dynamic_libpath: trying
"C:/mysys64/mingw64/lib/my_extension"
DEBUG: mapped win32 error code 3 to 2
DEBUG: mapped win32 error code 3 to 2
DEBUG: find_in_dynamic_libpath: trying "C:/Program
Files/PostgreSQL/17/lib/my_extension.dll"
DEBUG: mapped win32 error code 2 to 2
DEBUG: mapped win32 error code 2 to 2
DEBUG: find_in_dynamic_libpath: trying
"C:/msys64/mingw64/lib/POSTGR~1/my_extension.dll"

ERROR: could not load library
"C:/msys64/mingw64/lib/POSTGR~1/my_extension.dll": The specified module
could not be found.
SQL state: 58P01

my_extension is in the latter dir.

Can you offer any advice or help to fix this issue?
Thank you in advance,
Conor

Browse pgsql-docs by date

  From Date Subject
Next Message PG Doc comments form 2024-11-29 12:06:20 pg_createsubscriber: publication-name and subscription-name options do not exist
Previous Message Peter Smith 2024-11-25 00:55:12 Re: Logical replication - initial data synchronization