千家信息网

PostgreSQL中怎么实现跨平台

发表于:2025-02-22 作者:千家信息网编辑
千家信息网最后更新 2025年02月22日,今天就跟大家聊聊有关PostgreSQL中怎么实现跨平台,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。#include "dynloader.
千家信息网最后更新 2025年02月22日PostgreSQL中怎么实现跨平台

今天就跟大家聊聊有关PostgreSQL中怎么实现跨平台,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

#include "dynloader.h"
mysql_dll_handle = dlopen(_MYSQL_LIBNAME, RTLD_LAZY | RTLD_DEEPBIND);改为mysql_dll_handle = dlopen(_MYSQL_LIBNAME, 1);

更正规的写法是

#if defined(__APPLE__) || defined(__FreeBSD__)  mysql_dll_handle = dlopen(_MYSQL_LIBNAME, RTLD_LAZY);#elif defined WIN32  mysql_dll_handle = pg_dlopen(_MYSQL_LIBNAME, 1);#else  mysql_dll_handle = dlopen(_MYSQL_LIBNAME, RTLD_LAZY | RTLD_DEEPBIND);#endif

这里并没有修改原有两行,只是为展示应该怎么写,模块代码的跨平台性才会更好些。

dynloader.h在编译前会根据平台指向正确的头文件,在Windows下指向 src/backend/port/dynloader/win32.h

#define pg_dlopen(f)       dlopen((f), 1)#define pg_dlsym           dlsym#define pg_dlclose         dlclose#define pg_dlerror         dlerrorchar   *dlerror(void);int     dlclose(void *handle);void   *dlsym(void *handle, const char *symbol);void   *dlopen(const char *path, int mode);

Windows下封装了库载入的系列函数,它们实现在 src/backend/port/dynloader/win32.c,节选:

void *dlopen(const char *path, int mode){  HMODULE    h;  int      prevmode;  /* Disable popup error messages when loading DLLs */  prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);  h = LoadLibrary(path);  SetErrorMode(prevmode);  if (!h)  {    set_dl_error();    return NULL;  }  last_dyn_error[0] = 0;  return (void *) h;}

最终,仍然是调用传统的Windows函数LoadLibrary。

前文还提到修改Solution.pm,只为mysql_fdw添加库和头文件路径,避免影响其他模块。因为mysql有些头文件跟PG定义冲突,大家都是关系数据库,难免有些东西的命名会相同 @_@。

上边说的是编译系统自动识别当前平台,编译不同源文件,*nix平台是在configure脚本里。

平台判断:

case $host_os in     aix*) template=aix ;;  cygwin*) template=cygwin ;;  darwin*) template=darwin ;;dragonfly*) template=netbsd ;; freebsd*) template=freebsd ;;    hpux*) template=hpux ;; linux*|gnu*|k*bsd*-gnu)           template=linux ;;   mingw*) template=win32 ;;  netbsd*) template=netbsd ;; openbsd*) template=openbsd ;; solaris*) template=solaris ;;esac

指定软链文件(比如macOS会指向 src/backend/port/dynloader/darwin.h)

    "src/include/dynloader.h") CONFIG_LINKS="$CONFIG_LINKS src/include/dynloader.h:src/backend/port/dynloader/${template}.h" ;;

再来看Windows(Solution.pm中),用的是拷贝方式:

  if (IsNewer(      'src/include/dynloader.h', 'src/backend/port/dynloader/win32.h'))  {    copyFile('src/backend/port/dynloader/win32.h',      'src/include/dynloader.h');  }

当然,代码里更多的是传统preprocessor方式:

#ifdef WIN32    /* Win32 does not have UTF-8, so we need to map to UTF-16 */    if (GetDatabaseEncoding() == PG_UTF8      && (!mylocale || mylocale->provider == COLLPROVIDER_LIBC))    {...#endif              /* WIN32 */

看完上述内容,你们对PostgreSQL中怎么实现跨平台有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

0