1. 程式人生 > >PostgreSQL如何實現跨平臺程式碼

PostgreSQL如何實現跨平臺程式碼

我們知道,PostgreSQL可以支援幾乎(這個詞似乎可以不要)所有主流平臺,平臺間尤其Windows與*nix之間的API差異巨大,PG是怎麼做到的呢,用一個簡單的例子解釋。

前邊我寫怎麼在Windows下編譯mysql_fdw提到過的修改:

#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		dlerror

char   *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如何實現跨平臺程式碼

我們知道,PostgreSQL可以支援幾乎(這個詞似乎可以不要)所有主流平臺,平臺間尤其Windows與*nix之間的API差異巨

“前.NET Core時代”如何實現跨平臺程式碼重用 ——程式集重用

  除了在原始碼層面實現共享(“前.NET Core時代”如何實現跨平臺程式碼重用 ——原始檔重用)之外,我們還可以跨平臺共享同一個程式集,這種獨立於具體平臺的“中性”程式集通過建立一種名為“可移植類庫(PCL: Portable Class Library)”專案來實現。

HBuilder的擴充套件外掛開發暴露了一個事實:其實不能實現寫一次程式碼實現跨平臺App生成

HBuilder的擴充套件外掛開發,原來並不能生成單獨的外掛jar,而是以原始碼 - 類的形式進行開發,這其實就要求必須使用離線打包。 事實上,開發順序應該是:先弄好離線打包框架,然後在AS裡進行擴充套件外掛開發,才能順利打包釋出。 這樣,其實android和ios平臺同樣是要分別用各自的原生語言開發擴充

java 是如何實現跨平臺的?

計算 生成 doc 計算機系統 純java 概述 成員 包括 文件 1、Java語言跨平臺的原理  首先什麽是平臺,平臺就是CPU處理器和操作系統的整體。如果計算機是人,那CPU就是人的大腦,它既負責思維運算,又負責身體各部件的命令控制。CPU的種類很多,   除去我們熟知

java如何實現跨平臺的?

不同的 版本 文件 machine clas 不同 如何實現 語言 程序 那麽,跨平臺是怎樣實現的呢?這就要談及Java虛擬機(Java Virtual Machine,簡稱 JVM)。JVM也是一個軟件,不同的平臺有不同的版本。我們編寫的Java源碼,編譯後會生成一種 .

使用Xamarin實現跨平臺移動應用開發(轉載)

def acs catch live make asset book -a 開發語言 剛在朋友圈看到張善友,轉發的一條分享“使用Xamarin實現跨平臺移動應用開發”,寫的確實很詳細得體,從收費到開源,這段時間xamarin受到不少質疑,如此文h

物聯網框架ServerSuperIO在.NetCore實現跨平臺的實踐路線

物聯 實現 strong image cor args 註意 right 正在 正所謂天下大勢,不跟風不行。你不跨平臺,很low嘛。java說:你們能跨嘛,跨給我看看。C#說:不要強人所難嘛。java說:能部署在雲上嗎?docker?微服務?C#說:不要強人

python paramiko模塊幸運飛艇平臺搭建實現跨平臺SSH

config 配置 set 交互 下載文件 興趣 fabri 命令執行 ftpclient 需求:在幸運飛艇平臺搭建論壇:haozbbs.com Q1446595067 管理用戶端(實際上所有支持Python的OS都可以)批量對遠程服務器進行部署、命令執行、文件傳輸、搭建測

搭建samba服務---實現跨平臺文件共享

免費軟件 samb netbios dac x86 cde 不同 計算機 tcp 概述 Samba是著名的開源軟件項目之一,它在Linux和UNIX系統上實現SMB協議的一個免費軟件,由服務器及客戶端程序構成。SMB(Server Messages Block

Google Protobuf——實現跨平臺跨語言的序列化/反序列化

Google Protobuf——實現跨平臺跨語言的序列化/反序列化 0 Overview Google Protocol Buffer 是一個平臺無關、語言無關的結構化資料的序列化與反序列化工具。 1 Establish dev environment wget http:

Laravel $model->save()的相關底層實現邏輯程式碼

    相信很多人就對這個問題很疑惑:    $model = new Model(); $mdoel->user_name = $userName;$mdoel->save();        

BP神經網路基於Tensorflow的實現程式碼註釋詳細)

BP(back propagation)神經網路是1986年由Rumelhart和McClelland為首的科學家提出的概念,是一種按照誤差逆向傳播演算法訓練的多層前饋神經網路,是目前應用最廣泛的神經網路。 在一般的BP神經網路中,單個樣本有m個輸入和n個輸出,在輸入層

使用 Web Essentials實現js程式碼塊摺疊

我們都知道.net後臺都有#region 、#endregion對功能塊程式碼進行摺疊,面對大量的程式碼時,摺疊起來非常方便。同樣面對大量的js指令碼怎麼實現向後臺一樣#region實現摺疊的 ,網上查了下 需要安裝這個擴充套件外掛“ Web Essentials”就能實現摺疊功能 1

Android仿ios微信左劃條目刪除、置頂的實現程式碼簡潔,更容易理解使用

<span style="font-family:Arial, Helvetica, sans-serif;"><span style="background-color: rgb(255, 255, 255);">歡迎大家</span></span

jenkins 整合maven,svn(配置鉤子程式實現提交程式碼自動構建),tomcat實現熱部署(windows+linux分別實現

1 準備工作: (1)執行jenkins的tomcat (2)執行我們專案的tomcat (3)SVN伺服器 jenkins就是一個war包,相信大家都非常熟悉,扔在tomcat  webapp下就能跑,具體操作步驟上網去搜一搜一大把,我們主要是來記錄一下如何實現鉤子程式,實現程式碼的動態部

十三種基於直方圖的影象全域性二值化演算法原理、實現程式碼及效果。

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Kaldi PLDA實現C++程式碼閱讀

PLDA(Probabilistic Linear Discriminant Analysis) 廣泛用於Speaker Verification中,這篇部落格主要記錄一下本人閱讀Kaldi中PLDA底層C++程式碼的過程。Kaldi中PLDA的實現主要參考Sergey Ioffe的這篇pa

微信小程式開發——使用wxParse外掛實現html程式碼的支援

前言: 大家都知道,無論是微信小程式還是支付寶小程式都不支援html程式碼的展示的,甚至說你想貼個純html程式碼做demo都不方便,更不用說解析html了。那麼怎麼解決這個問題呢? 解決方案: 使用WxParse外掛(微信小程式富文字解析元件)就能解決這個問題。本來這個外掛是專為微信小程式設計的,但是

HTML實現線上程式碼格式化、美化、加密、解密、壓縮、一鍵轉JavaScript功能工具-toolfk程式設計師工具網

 本文要推薦的[ToolFk]是一款程式設計師經常使用的線上免費測試工具箱,ToolFk 特色是專注於程式設計師日常的開發工具,不用安裝任何軟體,只要把內容貼上按一個執行按鈕,就能獲取到想要的內容結果。ToolFk還支援  BarCode條形碼線上生成、 

使用Docker實現php程式碼線上測試執行工具-toolfk.com

      本文要推薦的[ToolFk]是一款程式設計師經常使用的線上免費測試工具箱,ToolFk 特色是專注於程式設計師日常的開發工具,不用安裝任何軟體,只要把內容貼上按一個執行按鈕,就能獲取到想要的內容結果。ToolFk還支援  BarCod