如何使用 MSVC 编写 Postgres 语言处理程序
How to write a Postgres language handler using MSVC
这是直接从示例中提取的代码。 64 位安装,x64 构建。
#include "postgres.h"
#include "executor/spi.h"
#include "commands/trigger.h"
#include "fmgr.h"
#include "access/heapam.h"
#include "utils/syscache.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PGDLLEXPORT Datum plsample_call_handler(PG_FUNCTION_ARGS); // <-- the answer!!
PG_FUNCTION_INFO_V1(plsample_call_handler);
Datum
plsample_call_handler(PG_FUNCTION_ARGS)
{
Datum retval;
retval = 42;
return retval;
}
编译链接成功。这是 SQL:
CREATE FUNCTION plsample_call_handler() RETURNS language_handler
AS 'TryPostgresPl.dll'
LANGUAGE C;
CREATE LANGUAGE plsample
HANDLER plsample_call_handler;
这是错误消息。
ERROR: could not find function "plsample_call_handler" in file "C:/Program Files/PostgreSQL/9.5/lib/TryPostgresPl.dll"
SQL state: 42883
那么近又那么远。真的不知道去哪里看。
根据 Nick Barnes 进行编辑以显示答案。请注意,depends.exe 之前的 peek 显示了 2 个导出,现在是 3 个。
Postgres 文档中的示例直接针对 Linux 环境;显然 Windows 涉及更多内容。 an excellent article by @CraigRinger 在 Visual Studio 中解释了如何进行。
在这种情况下,看起来您只需要添加以下函数原型:
PGDLLEXPORT Datum plsample_call_handler(PG_FUNCTION_ARGS);
对我来说(Postgres 13 x64, VS2019, MSVC 14.27),在PG_FUNCTION_INFO_V1
前面加上PGDLLEXPORT
就够了,即:
PGDLLEXPORT PG_FUNCTION_INFO_V1(my_func);
仔细观察,这相当于:
PGDLLEXPORT extern Datum my_func(PG_FUNCTION_ARGS);
... plus a bunch more stuff
您会注意到这与已接受答案中手动完成的操作非常相似,因此这种方式似乎避免了一些重复。唯一的区别是 extern
关键字;老实说,我对 C 的了解还不够,不知道为什么把 PGDLLEXPORT
放在 extern
之前仍然有效(而不是像我在所有示例),但编译器不会抱怨并且扩展有效。
YMMV,特别是如果这些宏将来发生变化。
这是直接从示例中提取的代码。 64 位安装,x64 构建。
#include "postgres.h"
#include "executor/spi.h"
#include "commands/trigger.h"
#include "fmgr.h"
#include "access/heapam.h"
#include "utils/syscache.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PGDLLEXPORT Datum plsample_call_handler(PG_FUNCTION_ARGS); // <-- the answer!!
PG_FUNCTION_INFO_V1(plsample_call_handler);
Datum
plsample_call_handler(PG_FUNCTION_ARGS)
{
Datum retval;
retval = 42;
return retval;
}
编译链接成功。这是 SQL:
CREATE FUNCTION plsample_call_handler() RETURNS language_handler
AS 'TryPostgresPl.dll'
LANGUAGE C;
CREATE LANGUAGE plsample
HANDLER plsample_call_handler;
这是错误消息。
ERROR: could not find function "plsample_call_handler" in file "C:/Program Files/PostgreSQL/9.5/lib/TryPostgresPl.dll"
SQL state: 42883
那么近又那么远。真的不知道去哪里看。
根据 Nick Barnes 进行编辑以显示答案。请注意,depends.exe 之前的 peek 显示了 2 个导出,现在是 3 个。
Postgres 文档中的示例直接针对 Linux 环境;显然 Windows 涉及更多内容。 an excellent article by @CraigRinger 在 Visual Studio 中解释了如何进行。
在这种情况下,看起来您只需要添加以下函数原型:
PGDLLEXPORT Datum plsample_call_handler(PG_FUNCTION_ARGS);
对我来说(Postgres 13 x64, VS2019, MSVC 14.27),在PG_FUNCTION_INFO_V1
前面加上PGDLLEXPORT
就够了,即:
PGDLLEXPORT PG_FUNCTION_INFO_V1(my_func);
仔细观察,这相当于:
PGDLLEXPORT extern Datum my_func(PG_FUNCTION_ARGS);
... plus a bunch more stuff
您会注意到这与已接受答案中手动完成的操作非常相似,因此这种方式似乎避免了一些重复。唯一的区别是 extern
关键字;老实说,我对 C 的了解还不够,不知道为什么把 PGDLLEXPORT
放在 extern
之前仍然有效(而不是像我在所有示例),但编译器不会抱怨并且扩展有效。
YMMV,特别是如果这些宏将来发生变化。