測試並改良 Python-Solvespace wrapper:

  • 端口更新相容至 Windows 平台

端口更新

在 Windows 平台由於使用 MinGW 編譯,因此不會用到 Visual studio 的工具。

在編譯流程的測試上,也須要更多設定。

平台差異

  1. Define WIN32

    大部分 C++ 的 Windows 腳本要求都放在此定義中。

  2. Define _USE_MATH_DEFINES

    加入此值表示使用 cmath 的內容。

  3. 加入 platform/platform.cpp

    切換成 platform/w32util.cpp 後,其中會用到 platform/platform.cppPlatform::Narrow(wchar_t) 函式。

    因此會加入 platform.o 的編譯需求。

  4. 加入 config.h

    原先的 config.h 有紀錄一些設定:Solvespace 版本、安裝位置、GL 函式庫版本,不過是透過 CMake 填入樣板 config.h.in 產生的。

    顯然之後配置 CMake list 的時候沒有為獨立 solver 做切割。

    platform/platform.cpp 只是 FindLocalResourceDir 函式需要用到 UNIX_DATADIR 而載入,因此修改 CMake 的 template,有定義 UNIX_DATADIR 即可,路徑亂給也不會用到。

    標頭檔不需要寫給編譯器看,只要放著即可。

綜上述要求,Makefile 執行時會先做這些步驟:

ifeq ($(OS), Windows_NT)
    CFLAGS += -DWIN32 -D_USE_MATH_DEFINES
    OFILES += $(OBJDIR)/w32util.o $(OBJDIR)/platform.o
else
    OFILES += $(OBJDIR)/unixutil.o
endif

提醒一下,由於設定了 Makefile 的 VPATH 參數,相當於 Python 的 sys.path

有紀錄 srcsrc/platform,可以用 % 符號來在這些區域中搜尋原始碼,不過要注意撞名問題。

因此可以從 $(OBJDIR)/%.o: %.cpp $(OBJDIR) 這個 target 中抓到 $(OBJDIR)/platform.o 的位置 src/platform/platform.cpp

VPATH = src src/platform

同理,若存在其他目錄的原始碼,想用 %.cpp%.o 的指令寫簡單一點,就必須把目錄加到 VPATH。

編譯測試

原本想讓 platform/w32util.cpp 簡單一點,不使用 platform/platform.cpp,於是切斷了 InitPlatform 函式的連結,改成類 Unix 平台的方式回傳,沒想到編譯出來後,Python 載入動態函式庫會馬上卡死無法執行,而且也不會回報錯誤。

因此只好連同編譯 platform/platform.cpp,不過又遇到 LoadResource 函式中使用的 FindResourceW 函式有類型轉換問題。

HRSRC hres = FindResourceW(NULL, Widen(name).c_str(), RT_RCDATA);
cannot convert 'LPSTR {aka char*}' to 'LPCWSTR {aka const wchar_t*}' for argument '3' to
'HRSRC__* FindResourceW(HMODULE, LPCWSTR, LPCWSTR)'

指的是第 3 個參數 RT_RCDATA

據測應該是 Windows.h 的函式,因此上網查詢此函式的接收值。

其中為 FindResourceFindResourceWFindResourceA 的原型,只差在編碼不同,FindResourceW 是 UTF 的形式。

HRSRC WINAPI FindResource(
  _In_opt_ HMODULE hModule,
  _In_     LPCTSTR lpName,
  _In_     LPCTSTR lpType
);

其中有列出 lpType 第 3 個參數可以使用的對象,但是其中明明就有 RT_RCDATA

出於無奈,搜尋使用此函式的原始碼,發現都不是 solver 的,加上 #if !defined(LIBRARY) 的要求後,編譯 solver 就不會用到。

最後終於編譯成功了,而且測試用的 Python script 可以正常執行。

還在考慮如何收拾目錄中編譯後的檔案,讓程式庫不會跟暫存的檔案混在一起,整理之後應該就能整合進 Pyslvs 了。


Comments

comments powered by Disqus