ZEMAX OpticStudio 如何編譯用戶自定義DLL

如何編譯用戶自定義DLL


概述


本文將介紹什么是用戶自定義DLL以及如何在Visual Studio中編譯用戶自定義DLL。本教程是基于Visual Studio Community 2017 version 15.9而創(chuàng)建的,但這些步驟在更早的版本中也適用,版本間變化指出均有記載。本文也會討論其他的編譯器。請注意本文不涉及如何編寫DLL。


OpticStudio專業(yè)版和旗艦版允許用戶使用C或C++程序建立他們自己的組件。有很多編譯器可以編譯C/C++代碼,其中很常用的是Visual Studio。本文將提供一步步的編譯DLL的指南。



什么是用戶自定義DLL?


空間頻率分為不同的頻域:
■ 在序列模式中,表面定義了光學材料的界面。表面類型可以是折射、反射、衍射或者漸變折射率。OpticStudio支持超過65種不同的表面類型,包括非常普適的面型包括多項式面型和雙錐Zernike。
然而,很多時候用戶依舊希望可以根據(jù)他們的具體需求訂制一些功能。這就是用戶自定義面型有用且強大的地方了,因為OpticStudio包含使用它的界面。

■ 在非序列模式中,物體定義了光學材料的界面。物體擁有帶有材料屬性的幾何形狀,且可以有面(face)來折射或者散射光線。材料也可以散射光線。物體也可以是個光源。
OpticStudio有針對上述所有類型的內(nèi)建的物體和屬性。在非序列模式中。所有的這些都可以通過以下的DLL來訂制:用戶自定義物體、GRIN檔案、衍射算法、體散射算法、用戶自定義光源。



64位系統(tǒng)要求


過去,OpticStudio曾發(fā)布過32位和64位程序,這意味著根據(jù)不同的OpticStudio,32位和64位的DLL都可能存在。現(xiàn)在,OpticStudio只支持64位的應用。如果在使用DLL時彈出以下錯誤信息,那么源代碼必須使用本文的步驟重新編譯。


注意:對于老的Visual Studio,可能需要安裝的額外的64位編譯程序包,具體步驟請見:

Windows SDK 7.1(https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=8279)。下載后,找到Tools…Options…Environment…Projects and Solutions。在該窗口勾選“Show advanced build configurations”且保證設置如下:



Tools…Options和“Project Properties”對話框里的不一樣。


64位系統(tǒng)要求


一般設置


DLL文件(Dynamic Link Library)是Visual Studio的一種輸出類型。為了建立一個DLL,我們先創(chuàng)建project space來放置代碼。

在Visual Studio種找到File…New…Project。



在Visual C++選項下,選擇Windows Desktop Wizard項目類型。



接著選擇Application類型為“Dynamic Link Library (.dll):



當項目(project)創(chuàng)建好之后,第一件要做的事情是改變build type。找到Build…Configuration Manager…


在Configuration Manager中,我們把solution configuration設置為“Release”,以便在代碼運行后獲取一個DLL。選項platform需設為“x64”。這意味著代碼只會兼容64位系統(tǒng)和應用程序。




接下來,添加Source File。Source File必須是CPP類型,所以選擇“New Item…”并選擇C++ File。




在文件下{Zemax}\DLL下,有很多可以參照的用戶自定義代碼的示范文件。如果要使用其中某個文件,把其代碼復制到剛才新建的C++ Source File中。


當案例文檔載入后,一些項目屬性需要修改。右鍵點擊項目名稱并選擇“Properties”。



在Configuration Properties…General中,確?!癈onfiguration Type”已經(jīng)設為“Dynamic Library (.dll)”,并且把“Character Set”設置為“Use Multi-Byte Character Set”。



注意:更早版本的Visual Studio會需要本文開頭提到額外下載包,且需要設置它門的“Platform Toolset”為Windows7.1SDK。


然后,在Configuration Properties…C/C++…Code Generation選取“Runtime Library”。一般地,我們推薦使用Multi-threaded (/MT)或者Multi-threaded DLL (/MD)。
Multi-threaded與Multi-threaded DLL之間的選擇比較復雜,但大體上是兼容性和易用性之間的選擇。如果該用戶自定義DLL不依賴于其他庫(library),那么使用Multi-Threaded runtime library意味著不考慮在本電腦上安裝使用該DLL的C++ redistributable。如果在本DLL中,需要用到其他的庫,那么就需要在此選取那個runtime庫,而在絕大多數(shù)情況下,它都是Multi-Threaded DLL runtime。
對于簡單的不調(diào)用第三方庫的DLL,Multi-threaded runtime是最佳選擇。



一旦以上設定宣告完畢,點擊OK來退出Properties對話框。


檢查代碼錯誤


現(xiàn)在,我們來檢查并確保所有內(nèi)容都能被母代碼識別。如果該DLL是個用戶自定義表面且source file路徑不在{Zemax}\DLL\Surfaces文件夾,那么頭文件“usersurf.h”會不被認可(由紅色下劃線表征)。



為修正這個問題,直接把 {Zemax}\DLL\Surfaces下面的“usersurf.h”復制并粘貼到source code同一個路徑下,然后右鍵點擊“Header Files”來載入頭文件并導入現(xiàn)有的代碼中。



當頭文件載入到正確的路徑后,紅色下劃線應該就不再出現(xiàn)了。如果有任何內(nèi)容未被讀出,那么該DLL可能不能編譯。即使編譯了,也未必能正常運行。


使用C++編譯器


絕大部分Zemax自帶的案例文件都是用C語言寫的。由于Visual Studio是個C++編譯器,這意味著必須對代碼進行一些修改來正確地編譯它們。


如果還沒添加。那么在代碼開頭的初始化功能區(qū)放入“extern “C” {}”。同時確保把“BOOL WINAPI DllMain”這一行注釋掉。




在C++編譯器里,程序(function)名往往會在后臺被修改,以使得每個程序都有其唯一的標識。如果程序名變化了,那么OpticStudio會無法運行該DLL,因為OpticStudio會尋找具體的名稱(例如:UserDefinedSurface、UserObjectDefinition等)采用上述改變可以強制編譯器保持原來C代碼里的程序名且忽略任何可能造成的錯誤。


同樣地,可能也會需要無視由于C和C++的細微不同造成的警告,例如:
C4996: ‘srtcpy’: This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.


如果這是編譯中唯一遇到的警告,那么以下的代碼可以繞過這個問題:
#pragma warning ( disable : 4996 )



這行代碼會允許編譯器提供特定于電腦或者操作系統(tǒng)的功能,同時保持C和C++語言上大體的兼容性。


Rebuild Solution


選擇Build…Rebuild Solution來編譯你的代碼,或者直接按鍵盤“Ctrl+F5”。編譯成功后會輸出以下內(nèi)容:



這個DLL會在solution文件夾下。對于“My_Surface”這個項目而言,該DLL會在{Project directory}\My_Surface\x64\Release。



編譯器



以下版本的Visual Studio都可以用來編譯OpticStudio的用戶自定義DLL:
■ 2005, 2008
■ Express 2010, Express 2012
■ Community 2017, Community 2019
請閱讀https://visualstudio.microsoft.com/zh-hans/vs/community/來了解使用條件。


除了Visual Studio之外,任何其他64位的C語言編譯器只要可以創(chuàng)建多線程的Windows DLL project,那么都可以使用。有很多不同的編譯器可供選擇。如果在使用其他編譯器時遇到技術(shù)問題,請聯(lián)系他們的技術(shù)支持詢問以下問題:“如何創(chuàng)建空的多線程Win32 DLL project?”


OpticStudio中編寫特定面型、光源等DLL的功能是非常強大的,它可以建立更加準確的系統(tǒng)模型。

參考資料



以下網(wǎng)頁可以幫助你理解案例代碼中用到的命令:


C++語言官網(wǎng)