eXe
eXe

Reputation: 194

How to make PostgreSQL to load a C-module that depends on a DLL?

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 sumfunction that adds two numbers returned by the numberfunction 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

Answers (1)

eXe
eXe

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

Related Questions