Building Windows Server Extensions Using VC++ 2005 - Mailing list pgsql-hackers
From | Charles F. I. Savage |
---|---|
Subject | Building Windows Server Extensions Using VC++ 2005 |
Date | |
Msg-id | 4390ECC8.8060309@interserv.com Whole thread Raw |
Responses |
Re: Building Windows Server Extensions Using VC++ 2005
|
List | pgsql-hackers |
Hi everyone, I've been able to successfully build server extension using Visual Studio 2005 for Windows Postgresql 8.1. However, it took a few tweaks which I thought I should document (maybe these issues could be fixed in future postgresql versions?): 1. There is no lib file for VC++ to link against. This can be created easily enough by going to src/backend directory and running: lib /MACHINE:x86 /NAME:postgres.exe /DEF:postgres.def Note the use of /NAME to tell VC++ it is linking against an executable and not a dll. It would be nice if this lib file was automatically installed on windows when installing postgresql. 2. Requirement on strings.h In c.h:69 there is this code: #ifdef HAVE_STRINGS_H #include <strings.h> #endif In pg_config.h:405 this is defined: /* Define to 1 if you have the <strings.h> header file. */ #define HAVE_STRINGS_H 1 However, Visual Studio 2005 does not include this file. For a workaround I simply added it but that's a bit of hack. 3. This is a bigger issue, and took a while to figure out. If you try to use the Version 1 calling convention, your function will be called but if you try to do anything with the passed in parameters a segmentation fault will occur. If you use the Version 0 calling convention things work fine. The problem is if you use PG_FUNCTION_INFO_V1 postgres does not see the generated function because it is not exported from the dll and thus assumes the Version 0 calling convention when in fact your function is using Version1. The problem is in fmgr.h:298 #define PG_FUNCTION_INFO_V1(funcname) \ extern Pg_finfo_record * CppConcat(pg_finfo_,funcname) (void); \ ... For windows to export this function it must be: extern __declspec(dllexport) Pg_finfo_record * CppConcat(pg_finfo_,funcname) (void); Would it be possible to add a DLLEXPORT macro here to fix this? 4. Last, and the biggest issue, if my function calls pfree it blows up. What is happening is that pfree somehow ends up pointing to a random spot in memory - thus when you try to call it you execute invalid code (in fact you never execute pfree at all as far as I can see). I worked around this by using pgport_pfree which does work. Haven't a clue why... Here is the assembly for successfully calling pgport_pfree: pgport_pfree(fileName); 100112D3 mov eax,dword ptr [ebp-0Ch] 100112D6 push eax 100112D7 call 100110C3 100112DC add esp,4 100110C3 jmp 1001131A pgport_pfree: 1001131A jmp dword ptr ds:[10016288h] 005CF140 push ebp 005CF141 mov ebp,esp 005CF143 sub esp,8 005CF146 mov eax,dword ptr [ebp+8] 005CF149 mov dword ptr [esp+4],eax 005CF14D mov eax,dword ptr ds:[006A9F94h] 005CF152 mov dword ptr [esp],eax 005CF155 call 005CF0D0 005CF15A leave 005CF15B ret And here is pfree. Note at the end the code tries to execute "db" at 005E1560 causing a segmentation fault. pfree( fileName ); 100112D3 mov eax,dword ptr [ebp-0Ch] 100112D6 push eax 100112D7 call 1001110E 100112DC add esp,4 1001110E jmp 10011238 pfree: 10011238 jmp dword ptr ds:[1001628Ch] 005E1560 db ffh Hope this helps others. It would be great if building postgresql server extensions with VC++ worked out of the box on Windows (in addition of course to using MingW) since I think it would open up a wider audience. Charlie
pgsql-hackers by date: