測試並改良 Python-Solvespace wrapper:
- 端口更新相容至 Windows 平台
端口更新
在 Windows 平台由於使用 MinGW 編譯,因此不會用到 Visual studio 的工具。
在編譯流程的測試上,也須要更多設定。
平台差異
-
Define
WIN32:大部分 C++ 的 Windows 腳本要求都放在此定義中。
-
Define
_USE_MATH_DEFINES:加入此值表示使用
cmath的內容。 -
加入
platform/platform.cpp:切換成
platform/w32util.cpp後,其中會用到platform/platform.cpp的Platform::Narrow(wchar_t)函式。因此會加入
platform.o的編譯需求。 -
加入
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。
有紀錄 src 和 src/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 的函式,因此上網查詢此函式的接收值。
其中為 FindResource、FindResourceW、FindResourceA 的原型,只差在編碼不同,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