繁体   English   中英

在Windows平台上创建PostgreSQL C扩展

[英]Creating PostgreSQL C extensions on Windows platform

从命令行和Visual Studio都尝试过后,我无法获得一些简单的测试功能以供Postgres链接和/或在Windows上运行。 我发现很少的文档,也没有适用的模板。

我不习惯Windows中的编译工具,而我是Postgres的新手,所以我可能缺少一些非常基础的东西。 任何方向将不胜感激!

使用:Windows 8.0(64位),cl.exe 18.00.21005.1,link.exe 12.00.21005.1,PostgreSQL v.9.3.4(二进制安装)。

这是文档中的示例代码,只是为了简单起见,我只添加了PGDLLEXPORT调用:

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

PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(add_one);

PGDLLEXPORT Datum
add_one(PG_FUNCTION_ARGS)
{
    int32   arg = PG_GETARG_INT32(0);

    PG_RETURN_INT32(arg + 1);
}

在我的cl命令文件中,我收集了以下包含路径:

/I "C:\Program Files\PostgreSQL\9.3\include\server\port\win32_msvc"
/I "C:\Program Files\PostgreSQL\9.3\include\server\port\win32"
/I "C:\Program Files\PostgreSQL\9.3\include\server\port"
/I "C:\Program Files\PostgreSQL\9.3\include\server"
/I "C:\Program Files\PostgreSQL\9.3\include"

然后运行:

cl /c add.c @includes
link /DLL add.obj "C:\Program Files\PostgreSQL\9.3\lib\postgres.lib"

它可以编译和链接而不会出现错误或警告。 我将创建的add.dll放在postgres \\ lib目录中,并定义了以psql用户postgres登录的相应函数:

CREATE FUNCTION add_one(integer) RETURNS integer
AS 'add','add_one'
LANGUAGE C STRICT;

我收到以下错误:

ERROR:  could not load library "C:/Program Files/PostgreSQL/9.3/lib/add.dll": %1 is not a valid Win32 application.

在Visual Studio中生成dll时,结果是相同的。

我最初打算编写的扩展更为复杂,并且还包括用于使用复合参数和返回值的“ funcapi.h”。 在这种情况下,它的编译也没有问题,但是在链接阶段失败,并出现以下类型的错误:

error LNK2019: unresolved external symbol _get_call_result_type ...
error LNK2019: unresolved external symbol _BlessTupleDesc ...
error LNK2019: unresolved external symbol _heap_form_tuple ...

同样使用命令行或MSVC,检查lib路径并尝试将\\ lib中所有可能的.lib依赖项添加到命令行中。 我也尝试了不同的调用约定。

但是,无论如何,我需要首先进行简单的DLL导出,并且解决方案可能与同一问题有关。

我猜想这可能与cl包含的系统默认值不匹配(32/64位?)有关,但是由于源仅包含来自postgres项目的标头,所以我希望该问题可以自动解决,而我不希望这样做。不知道该如何进行。

我写了一个关于这个主题的博客,可能会有用。 请参见使用Visual Studio在Windows上编译PostgreSQL扩展

您提到的标题问题已在9.4系列中修复。 我将看到有关为其后分支重新修补的信息。

而不是修改ch ,而应该在命令行上指定define:

/DWIN32

您还应该确保将代码编译为纯C

/Tc

当然,您必须在正确的Visual Studio命令提示符环境下运行,并且x86或x64编译器取决于所需的目标。 如果不确定,可以通过运行不带参数的cl.exe进行检查。 它将打印目标体系结构。

实际上这是可行的(命令行方法)。

我只是使用了错误的命令提示符版本,所以当使用与上述相同的步骤使用VS2012 x64交叉工具命令提示符时,我可以从postgres文档中获取所有示例功能。

编辑:如果您收到我在下面评论的编译错误C2011:'timezone':'struct'类型重新定义,请参见Craig Ringers答案以获得更好的处理方法。

如果其他人对此感到困惑,我还可以告诉我必须修改一个头文件include \\ ch,并添加以下内容:

#if defined(_WIN32)
#define WIN32
#endif

在代码的这一部分之前:

#if !defined(WIN32) && !defined(__CYGWIN__)     /* win32 includes further down */
#include "pg_config_os.h"       /* must be before any system header files */
#endif

没有它,您将得到编译错误。

(我是从这个线程那里得到的: 错误C2011:'timezone':'struct'类型redefinition(postgres) ,在接受的答案中,链接到带有差异列表的邮件列表)

我不知道这是否是在Windows中构建扩展的最佳方法,但是至少您不需要编译整个源代码树即可开始学习。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM