Reputation: 194
I have tried without success to create a C-language function in PostgreSQL from a module that depends on another DLL in Windows.
For example, let's suppose I want to create the sum
function that adds two numbers returned by the number
function that is in its own DLL.
The code for number.h
is:
#ifndef NUMBER_H
#define NUMBER_H
#ifdef NUMBER_EXPORTS
#define NUMBER_API __declspec(dllexport)
#else
#define NUMBER_API __declspec(dllimport)
#endif
extern "C" NUMBER_API int number();
#endif
and the code for number.cpp
is:
#include "number.h"
extern "C" int number() { return 1; }
The code for sum.cpp
is:
extern "C" {
#include <postgres.h>
#include <fmgr.h>
#include <utils/geo_decls.h>
#include "number.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
__declspec(dllexport) PG_FUNCTION_INFO_V1(sum);
Datum sum(PG_FUNCTION_ARGS)
{
int32 a {number()};
int32 b {number()};
int32 result {a + b};
PG_RETURN_INT32(result);
}
} // extern "C"
Suppossing that PostgreSQL is installed on C:\Program Files\PostgreSQL\9.5
, I create number.dll
and sum.dll
using this build.bat
file:
SET PG_DIR=C:\Program Files\PostgreSQL\9.5
SET PG_INCLUDES=/I%PG_DIR%\include /I%PG_DIR%\include\server /I%PG_DIR%\include\server\port\win32
CL number.cpp /EHsc /MD /DNUMBER_EXPORTS /LD
CL sum.cpp /EHsc /MD %PG_INCLUDES% /LD /link number.lib
Then I copy both DLLs to C:\Program Files\PostgreSQL\9.5\lib
and write the SQL for creating the function in sum.sql
:
CREATE OR REPLACE FUNCTION sum() RETURNS void AS
'sum'
LANGUAGE C STRICT;
After running psql -U postgres -f sum.sql
, I get the following error:
psql:sum.sql:3: ERROR: could not load library "C:/Program Files/PostgreSQL/9.5/lib/sum.dll": The specified module could not be found.
Note that this error is different from a "file not found" error. It seems that PostgreSQL finds the file, but does not recognize it as a valid module. However, if I create a static library of num.cpp
instead and link it against sum.dll
, then the function is created successfully. In other words, PostgreSQL loads the module only if it contains all the code it needs.
Why is this happening and how could I make PostgreSQL to know about number.dll
when creating the sum
function?
Upvotes: 0
Views: 1469
Reputation: 194
The directories of the dependent DLLs must exist in PATH
before PostgreSQL server is started.
Go to:
Control Panel
System and Security
System
Advanced System Settings
Advanced
Environment Variables
Path
Open it and add the full path of all directories where the dependent DLLs reside. Restart the PostgreSQL server and done, psql
will execute the C-module successfully.
Upvotes: 1