在 Windows 寫 Linux 程式:Visual Studio + Windows Subsystem for Linux

微軟的 VIsual Studio 在 Heresy 來看,算是 Windows 上最好的 C++ 開發環境,但是缺點就是沒有 Linux 版了。不過,微軟在這幾年正積極地往跨平台、開放原始碼的方向走,所以這部分的狀況倒也有些改變了~

在 2015 年,微軟也已經發表了跨平台的開發環境、Visual Studio Code,雖然還是沒有開放原始碼,但是也算是聊勝於無了。而同時,Visual Studio 2015 也加入了跨平台的程式開發功能!除了 Windows 外,也支援了 Android、iOS 以及 Linux~(不過當時 Heresy 想測試 Linux 的偵錯一直沒有成功就是了…)

這篇,則是 Heresy 看到微軟的 Visual C++ Team Blog 的《Targeting the Windows Subsystem for Linux from Visual Studio》後,才想起可以嘗試讓 Visual Studio 搭配 Windows 10 的 Bash on Ubuntu on Windows(Windows Subsystem for Linux、以下簡稱 WSL)來在單台 Windows PC 上、進行 Linux 上的 C++ 程式開發、偵錯

這篇的基本需求,主要是:

閱讀全文

使用 Qt 撰寫影片播放程式的一些紀錄

要使用 Qt 5 寫出一個撥放影片的程式,其實滿簡單的;因為 Qt 本身已經提供了一個「Qt Multimedia」的模組(文件),提供了以 QMediaPlayer文件)為主的類別、讓使用者可以快速地撰寫出一個撥放軟體了。

這邊 Heresy 則是記錄一下,最近使用他的一些紀錄。


基本使用

他最簡單的寫法,大概可以按照官方範例、寫成:

player = new QMediaPlayer;

playlist = new QMediaPlaylist(player);
playlist->addMedia(QUrl("http://example.com/myclip1.mp4"));
playlist->addMedia(QUrl("http://example.com/myclip2.mp4"));

videoWidget = new QVideoWidget;
player->setVideoOutput(videoWidget);

videoWidget->show();
playlist->setCurrentIndex(1);
player->play();

閱讀全文

Boost 與 Qt 的 Signal / Slot 效能測試

Qt 這個圖形介面的開發套件(官網),基本上算是目前數一數二的跨平台圖形介面開發方案了。

在 Qt 的架構中,要在不同的物件之間傳遞資訊、觸發事件,所使用的是其創造的「Signals & Slots」架構(官方文件)。

而目前除了 Qt 之外,還有許多函式庫,也有提供 Signals & Slots 的功能,像是 Boost C++ Libraries 裡面,就有 boost::signal 和 boost::signal2 這兩個函式庫可以使用;其中,Heresy 也有針對 boost::signal2 做過介紹(參考)。

在 Heresy 來看,Qt 的 signal & slot 的架構比較麻煩的地方,是他必須要使用許多非標準的語法,所撰寫的程式還需要經過 Qt Meta-Object Compiler(moc)來做前處理,才能讓一般的 C++ 編譯器編譯。相較之下,Boost 的 Signal2 在撰寫上的彈性就比較大、也比較方便了。

不過,這兩者個效能怎麼樣呢?這邊 Heresy 就是打算來做個簡單的效能評估。

閱讀全文

程式語言的漫畫《來吧!程式碼學園》

《はしれ!コード学園》(來吧!code 學園》這東西,是日本 Code IQ 網站(連結)上所連載的漫畫;他基本上是把好幾種程式語言給擬人化(萌化)之後,再來描述他們在「code 學園」裡的故事。

某方面來說,有點類似之前的《程式語言的擬人化/萌化》(part 1part 2),不過這邊這個還有彼此之間的互動,感覺算是更有趣吧~

漫畫連載的網頁是《【連載】はしれ!コード学園》,他從 2015/10 開始連載,目前最新的到第九話(2016/06、感覺似乎停了? @@)。

閱讀全文

OpenVR 搭配 OpenGL 的顯示方法

在今年五月的時候,Heresy 有寫了一篇《HTC Vive 開發方案:OpenVR 簡介》,大概介紹過 OpenVR(GitHub)粗略的架構了;當時 OpenVR 的版本還是 1.0.0,Heresy 主要是針對他的幾個模組的功用,做簡單的說明,並沒有認真地去講程式到底怎麼寫。

後來,其實 Heresy 算是有真得下去寫他的程式,也根據自己的需求、搭配 freeglut 重寫出一些小範例(GitHub)了。

到現在過了超過半年,OpenVR 也更新到 1.0.4 了,和 Heresy 剛開始研究時相比,不但 API 有做了一些修改,「hellovr_opengl」的程式內容,也做了相當程度的調整。

而這篇,就以「hellovr_opengl」這個官方範例,來大概紀錄一下怎麼寫 OpenVR 的 OpenGL 程式吧。

閱讀全文

Kinect for Windows 的 UWP 程式開發

Kinect for Windows SDK v2 是微軟推出的第二代深度攝影機的開發方案,不過也不知道為什麼,微軟在 2014 年之後,基本上都沒有針對他有什麼大動作,官方網站的 SDK 也是維持在 2014/10/21 的 2.0.1410.19000(連結)、沒有更新過。

而在 2015 年底的時候,Heresy 寫過一篇《在 Windows 10 使用 Kinect v2 進行人臉解鎖》,當時是可以透過強制更新驅動程式到 2.1.1511.11000,來使用 Windows Hello 的人臉辨識功能;但是遺憾的是,K4W SDK v2 也還是沒有更新…

而前幾天,微軟官方又發布了一篇《Kinect demo code and new driver for UWP now available》,說明了在 Kinect for Windows 開發方面的一些更新。

閱讀全文

讓函式回傳多個值:std::tuple

在 C++ 的規範裡面,一個函式基本上只能回傳一個值;但是實際上,很多時候,我們會希望、也有需要讓一個函式可以回傳超過一個值。

這時候,常見的方法大概會是兩個方向:

  1. 把要回傳的值,以函式的參數的形式,來做傳遞
  2. 建立一個特殊的結構、或類別,來把要回傳的值打包起來

前者感覺應該比較像是 C 的寫法,像是微軟的 Kinect for Windows SDK v2 基本上就可以說是這種風格;他把回傳值都用來回傳執行的結果,而真正的資料,則都是以參數來做傳遞。

後者基本上比較像是 C++ 的物件導向,也算是很常見的、很好實作的;像是 std::minmax()參考)就是把兩個回傳的值、以 std::pair<> 的形式來做封包、回傳。

閱讀全文

在 C++ 裡面呼叫外部程式 Boost.Process

如果想在 C++ 的程式裡面、呼叫外部的程式的話,一般傳統的做法,應該有使用 system()參考)或 C 風格的 popen() 這兩種方法(參考)。

不過,以 system() 來說,他並不能處理外部程式的輸出與輸入,在某些情況下不算實用。

popen() 的話,則是不存在於 MSVC 的環境中,需要使用替代的 _popen()MSDN)才行;同時,popen() 也僅有提供單向、不能雙向(只能寫或讀、不能同時讀寫);真要雙向的使用,其實相當地麻煩(參考)…

而 Boost.Process 則是一個還在開發中、也還沒正式進到 Boost C++ Libraries 的函式庫,他基本上就是希望可以提供一個跨平台、同時有更多功能的外部程序處理函式庫。

它的原始碼在:

https://github.com/klemens-morgenstern/boost-process

目前版本標記是 alpha06、需要搭配支援 C++11 的編譯器、以及 Boost 1.62.0 使用(試過 1.61 不行);文件則是在 http://klemens-morgenstern.github.io/process/

閱讀全文

跨平台的 plugin 開發函式庫:Boost DLL-搭配自訂類別

前面在《基本使用》、《進階》這兩篇文章,應該算是把 Boost.DLL 的一般使用狀況都大概寫過了;不過實際上,Heresy 這邊真正要拿來用的話,應該不會直接匯出函式或變數,而是會採用匯出自訂類別(class)的形式吧~

這樣的概念,主要是自己定義一個抽象類別,在裡面規範好需要那些變數、要實作哪些成員函式,之後就只需要操作這個類別的物件就好了~基本上,應該算是比較物件導向的做法。

而這偏就是來稍微寫一下,該怎麼透過 Boost.DLL、把自訂列別當作外掛的介面來用。


閱讀全文

跨平台的 plugin 開發函式庫:Boost DLL – 進階

這篇是延續前一篇《基本使用》,繼續來整理一些 Boost.DLL 的其他功能。


Alias(別名)

首先,是「alias」(別名)的部分。

在前一篇裡面,已經提過基本的匯出、匯入的方法了。在基本的方法中,要匯出和匯入時,都是直接使用本來的變數、函式名稱;但是有的時候,如果不方便直接使用原有的變數、函式名稱,但是又不好直接去改名的時候,就可以透過 alias 的機制,在匯出時採用另一個名字來匯出。

閱讀全文