I wrote a series of custom C PostgreSQL functions in Notepad++. I used the VS2015 x64 Native Tools command line utility to compile the code and linked it. No problems and worked perfectly.
But as much fun as coding in Notepad++ is, I decided to create a project in Visual Studio. After several hours of getting configurations correct, I can get the project to compile, but not link.
The specific errors are:
Error LNK2019 unresolved external symbol "double __cdecl DatumGetFloat8(unsigned __int64)" (?DatumGetFloat8@@YAN_K@Z) referenced in function "unsigned __int64 __cdecl wrapf64(struct FunctionCallInfoData *)" (?wrapf64@@YA_KPEAUFunctionCallInfoData@@@Z) ... Error LNK2019 unresolved external symbol "unsigned __int64 __cdecl Float8GetDatum(double)" (?Float8GetDatum@@YA_KN@Z) referenced in function "unsigned __int64 __cdecl wrapf64(struct FunctionCallInfoData *)" (?wrapf64@@YA_KPEAUFunctionCallInfoData@@@Z) ...
The symptom appears to be in fmgr.h (comments by me):
/* these macros hide the pass-by-reference-ness of the datatype: */
#define PG_GETARG_FLOAT4(n) DatumGetFloat4(PG_GETARG_DATUM(n)) // missing a definition
#define PG_GETARG_FLOAT8(n) DatumGetFloat8(PG_GETARG_DATUM(n)) // missing a definition
#define PG_GETARG_INT64(n) DatumGetInt64(PG_GETARG_DATUM(n))
Looking in postgres.h we see:
#ifdef USE_FLOAT8_BYVAL
extern float8 DatumGetFloat8(Datum X);
#else
#define DatumGetFloat8(X) (* ((float8 *) DatumGetPointer(X)))
#endif
There is no #define. Adding one doesn't resolve the issue.
By contrast:
#ifdef USE_FLOAT8_BYVAL
#define DatumGetInt64(X) ((int64) GET_8_BYTES(X))
#else
#define DatumGetInt64(X) (* ((int64 *) DatumGetPointer(X)))
#endif
This is the unedited source code of PostgreSQL and it worked from the command line utilities. What's the problem inside VS? Or, should I say, why did it work in the command line linker when the #define is missing?
Any suggestions?
One other question I have is my original code had abs(double ...) but inside VS I have to use fabs(double ...). Is this a C vs C++ point? I couldn't find a clear answer in MSDN.