c++ - 如何让 PostgreSQL 加载依赖于 DLL 的 C 模块?

标签 c++ postgresql visual-c++ dll

我曾尝试从依赖于 Windows 中另一个 DLL 的模块在 PostgreSQL 中创建 C 语言函数,但没有成功。

例如,假设我想创建 sum 函数,该函数将 number 函数返回的两个数字相加,该函数在其自己的 DLL 中。

number.h 的代码是:

#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

number.cpp 的代码是:

#include "number.h"
extern "C" int number() { return 1; }

sum.cpp 的代码是:

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"

假设 PostgreSQL 安装在 C:\Program Files\PostgreSQL\9.5 上,我创建了 number.dllsum.dll 使用这个 build.bat 文件:

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

然后我将两个 DLL 复制到 C:\Program Files\PostgreSQL\9.5\lib 并在 sum.sql 中编写用于创建函数的 SQL:

CREATE OR REPLACE FUNCTION sum() RETURNS void AS
'sum'
LANGUAGE C STRICT;

运行 psql -U postgres -f sum.sql 后,出现以下错误:

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.

请注意,此错误不同于“找不到文件”错误。 PostgreSQL 似乎找到了该文件,但未将其识别为有效模块。但是,如果我改为创建 num.cpp 的静态库并将其链接到 sum.dll,则函数创建成功。换句话说,PostgreSQL 仅在模块包含所需的所有代码时才加载该模块。

为什么会这样?我如何让 PostgreSQL 在创建 sum 函数时知道 number.dll

最佳答案

在 PostgreSQL 服务器启动之前,依赖的 DLL 目录必须存在于 PATH 中。

前往:

Control Panel
 System and Security
  System
   Advanced System Settings
    Advanced
     Environment Variables
      Path

打开它并添加依赖 DLL 所在的所有目录的完整路径。重新启动 PostgreSQL 服务器并完成,psql 将成功执行 C 模块。

关于c++ - 如何让 PostgreSQL 加载依赖于 DLL 的 C 模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38493087/

相关文章:

c++ - C++ 中读取大型 CSV 文件的性能问题

c++ - 模板函数调用被函数混淆,在模板之前声明了错误的签名

c++ - 将 getline() 字符串拆分为多个 int 和 char 变量?

docker中的Java应用程序: Failed to get driver instance for postgres

database - 数据库中的 CPU 利用率实际上意味着什么?

c++ - 如何将 LPTSTR 传递给函数并修改其内容

c++ - log4cpp 和链接错误

C++ 编译器错误 C2751 - 究竟是什么原因造成的?

winapi - 如何使用 C++ 获取 Windows 用户配置文件路径的父文件夹

mysql - (我的)仅使用 SQL 的解决方案来显示议程系统中的可用时间段