Building Windows Server Extensions Using VC++ 2005 - Mailing list pgsql-hackers

From Charlie Savage
Subject Building Windows Server Extensions Using VC++ 2005
Date
Msg-id dmt4eq$2tss$1@news.hub.org
Whole thread Raw
List pgsql-hackers
Hmm...this didn't seem to make it to the newsgroup.  Apologies if its a 
repeat.

Charlie

-------------
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
uppointing 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:

Previous
From: Josh Berkus
Date:
Subject: Re: SERIAL type feature request
Next
From: "Qingqing Zhou"
Date:
Subject: Re: Building Windows Server Extensions Using VC++ 2005