用 Boost::Beast 刻的 Http Client

這篇算是簡單紀錄一下,Heresy 自己用 Boost::Beast(官網)刻出來的簡易的 C++ Http client 端函式庫。

Heresy 自己會寫這個,主要是因為有寫一個小程式,去把特定網站的內容,自動下來後重新整理、再轉換成電子書的格式給 Kindle 用。

其實第一個版本,Heresy 是用 Boost::asio(官網)來寫的;但是後來那個網站改成 HTTPS 了,所以程式就不能用了…拖了好一陣子後,Heresy 終於下定決心,改用 Boost::Beast 這個稍微高階一點的函式庫,來重寫 Http 的部分了。 ^^"

相關的檔案都放在:

https://github.com/KHeresy/HttpClientLite

閱讀更多»

廣告

在 Visual Studio 2017 建置 OpenCC

很久以前,Heresy 有寫過《OpenCC 簡易使用紀錄》這篇文章,簡單記錄當時使用 OpenCC 的情況了。而最近,由於又要改動相關的程式,所以就又需要重新建置它了。

但是沒想到,按照之前建置的方法,在 Visual Studio 2017 下,卻出現了一些問題…

問題主要有兩個:

  1. PhraseExtract.cpp 這個檔案會出現 C2059、C2001 等語法錯誤
  2. 編譯 Config.hcpp 的時候,VC 提供的 setjmp.h、csetjmp 兩個檔案出現 C3829 等錯誤

閱讀更多»

在 VIsual Studio 使用 Just My Code,避免 C++ 偵錯時顯示大量外部函式庫的內容

在使用 Visual C++ 開發程式的時候,其實有許多好用的偵錯工具,都可以幫助開發者找到程式的問題到底在哪;包括了各種中斷點、呼叫堆疊(call stack)、以及逐步執行(step)等等,能善用的話,都是很方便的工具。

但是,當外部函式庫使用多了之後,其實在使用呼叫堆疊和逐步執行的時候,往往會碰到一個問題,那就是外部函式庫會造成嚴重的干擾,讓偵錯變得相當麻煩…

比如說下面就是 Heresy 自己用 Boost Beast 來試著寫 WebSocket Server 時,中斷時的呼叫堆疊:

閱讀更多»

允許 32 位元應用程式使用 2GB 以上的記憶體

目前大部分的電腦系統,應該都已經從 32 位元轉換到 64 位元了,所以在開發應用程式的時候,其實在一定的程度上,可以「揮霍」記憶體。(笑

但是,有的時候受限於第三方函式庫,可能還是需要建置 32 位元的程式;實際上,Heresy 這邊最近就有碰到,因為廠商硬體的驅動程式的原因,無法把程式建置成 64 位元的版本。

而只能建置成 32 位元的最大問題,就是記憶體使用量大幅變小了…

基本上,在 Windows 環境下,32 位元的應用程式能使用的記憶體,最大就是 1.6GB 左右了;如果程式向系統要求要求超過 1.6GB 的記憶體,就會出錯了。

閱讀更多»

shared_ptr 的輔助類別 enable_shared_from_this

之前在《避免 memory leak:C++11 Smart Pointer》()這兩篇文章,已經大概介紹了 C++11 的智慧指標(smart pointer)了。而 C+11 提供的三種智慧指標裡面,可能被使用的機會最大的,應該還是 shared_ptr<>參考)吧?

而最近在看 Boost 的 Beast 這個新的函式庫(官網)的時候,才注意到原來 C++11 還有提供一個 enable_shared_from_this<> 類別(參考),讓一個物件可以更安全地產生對應的智慧指標。

由於感覺還算滿有用的,所以這邊就稍微紀錄一下吧。

閱讀更多»

在 QTableView 內使用 QItemDelegate 來畫按鈕

QTableView 是 Qt 的一個 model / view 的表格元件(官方文件),如果搭配 QAbstractItemModel 來使用的話,其實還算簡單好用,甚至可以很簡單地做到多個表格間的資料同步。

而如果需要表格內不只想要顯示文字、而希望可以使用一般的 QWidget 的話呢,他其實也有提供 setIndexWidget() 這個函式(文件),可以針對每一個欄位,來設定要使用的 widget。

或者另一個選擇,就是放棄使用 QAbstractItemModel,改用 QTableWidget參考),也是一個方法。

閱讀更多»

C++ 資料成員初始化 @ C++11/17(inline variable)

在 Heresy 來看,C++ 類別(或結構)的資料成員(data member)的初始化,其實一直很麻煩…因為要初始化他的值,不能像一般變數一樣,在宣告的同時就同時定義,變成要初始化的話,會變成一定要去定義類別的建構子才行…

以前的寫法,基本上就是:

class CTest
{
public:
	int m_iValue1;
 
public:
	CTest() : m_iValue1(128)  {}
};

這樣寫法一個比較麻煩的地方,就是如果有好幾個建構子的話,那每個建構子都給各自去給初始化的值。

閱讀更多»

C++ 的一些 attribute

C++ 的 attribute(參考)是在 C++11 新加入的東西。他基本上算是在程式碼裡面,加上特別的輔助說明,給編譯器看,讓編譯器可以在編譯時針對這些屬性來做處理。

這樣的功能其實以前編譯器大多是有自己定義。像 gcc 是用 __attribute__參考)、MSVC 則是有 __declspec參考,現在則算是終於有個統一的標準了。

目前 C++ attribute 的寫法滿特別的,他是直接用兩組中括號夾住、寫成 [[…]] 這樣的形式。而到 C++20 為止,也訂了超過十個 attribute 了(到還沒定案的 C++20)(除了標準定義的部分,編譯器也還有可以有自己定義的東西);在大部分的狀況下,他們主要的功能大概就是避免編譯器產生不必要的警告、增加程式碼的可讀性,以及讓編譯器更好最佳化吧~

其中有的個人覺得還算滿有用的,所以這邊就大概紀錄一下。

閱讀更多»

在 Visual Studio 2017 使用 CUDA 9.2

雖然 Heresy 個人算是滿早期開始接觸 NVIDIA CUDA 的,但是其實已經沒有在碰 NVIDIA CUDA 程式好一段時間了…不過,由於在開發的專案裡面,還是有一些地方有用到別人寫的 CUDA 程式,所以在維護的時候,還是需要去考慮他。

而根據從以前到現在的經驗,NVIDIA 針對 Visual Studio 的支援,一向不是做得很快、很好;往往 Visual Studio 已經出了新版本了,CUDA 才終於支援上一個版本…

某方面來說,這應該也是由於 NVIDIA CUDA 的重點是高速計算、大部分這個領域的用戶,其實都是把程式放在 Linux 叢集上跑的關係吧?但是,這對於一般 Windows 的開發者來說,其實還滿麻煩的…

最近,Heresy 在把手邊的專案移植到 Visual Studio 2017 上,CUDA 又出現問題了… orz

閱讀更多»

在 header 檔使用 constexpr 定義全域變數

這邊是看到《Quick Q: use of constexpr in header file》這篇文章,覺得還滿實用的,所以來記錄一下;他基本上是有人在 StackOverflow 上有人提出這個問題(頁面)後,相關的討論。

首先,「constexpr」這個關鍵字,是在 C++11 加入的東西(參考);它的用處,是將變數或函式宣告為可以在編譯階段(compile time)就可以計算出他的值。

透過這個關鍵字,除了可以讓編譯器在編譯時就針對這些東西最佳化外,更有可能讓寫出更多在編譯階段展開的語法。像是 C++17 的「if constexpr」(參考),也可以在撰寫某些程式時、更為方便。

而在某些地方,也可以看到有人建議用 constexpr 來取代 #define,來作為更好的變數定義(至少會是 type-safe 的)。

而這邊的問題是:

可以在 header 檔中,使用 constexpr 來定義變數嗎?當多個 .cpp 檔去 include 他的時候,會不會產生多個實體、或是造成變數重定義的問題?

閱讀更多»