日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

BCC(Borland C++ Compiler)编译 ISAPI 扩展或者用MinGW也行

發布時間:2024/3/26 c/c++ 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BCC(Borland C++ Compiler)编译 ISAPI 扩展或者用MinGW也行 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天突發神經,要寫個ISAPI擴展,找了一下編譯器,發現VS 2017的大小>VS 2015 > VS 2013 > VS 2010 > VS 6 & SP6>BCC,于是下了個BCC,很久沒用過BCC,不知道它居然升級了,從2000年的Borland C++ 5.5.1升級到了2016年的Embarcadero C++ 7.20,編譯器名稱也改了。

bcc32.exe -> bcc32c.exe

brcc32.exe -> rc.exe

所以在Code::Blocks里面,Auto-detect不了7.2版本的,只有再下了個5.5的。下載完了,發現忘記怎么寫ISAPI了,幸好以前的馬甲在CSDN里留了個BCC編譯ISAPI的文章,還能baidu到,于是照本宣科,結果卻編譯不了,經過N次調試,總算成功了,于是總結一下以免備忘,萬一以后還要BCC寫ISAPI呢。

1,下載Borland C++ Compiler 5.5,解壓到D:\Borland\BCC55

2、下載Code::Blocks 16.01,安裝完后打開CodeBlocks,先不管默認編譯器,進入IDE界面

打開菜單Settings-Compiler...

Selected Compiler選擇Borland C++ Compiler (5.5 - 5.82)

Search Directories 選項卡里,Compiler添加D:\Borland\BCC55\Include,Linker添加D:\Borland\BCC55\Lib和D:\Borland\BCC55\Lib\PSDK

Toolchain executables 選項卡里,Compiler's installation directory輸入D:\Borland\BCC55

Other settings 選項卡里,點擊Advanced options,彈出一個窗口

Commands 選項卡里,Command選擇Link object files to dynamic library,Command line macro里將宏改一下,添加一個$def_input變量

原來的宏:$linker -q $libdirs -Tpd $link_options $link_objects,$exe_output,,$libs,,$link_resobjects

改變的宏:$linker -q $libdirs -Tpd $link_options $link_objects,$exe_output,,$libs,$def_input,$link_resobjects

OK - OK,保存設置

3,打開菜單File - New - Project...,選擇Shared Library,下一步,選擇C,下一步,填寫工程名,比如:test,下一步,OK

4,打開main.c,編寫代碼,其實我是復制微軟官網的代碼,改了一下, 能編譯通過就行

#define WIN32_LEAN_AND_MEAN #include <stdio.h> #include <httpext.h>#ifndef HSE_REQ_SET_FLUSH_FLAG #define HSE_REQ_SET_FLUSH_FLAG (HSE_REQ_END_RESERVED+43) #endifDWORD SendOutputToClient(IN EXTENSION_CONTROL_BLOCK *pecb, IN DWORD msecDelay); DWORD SendOutputToClient(IN EXTENSION_CONTROL_BLOCK *pecb, IN DWORD msecDelay, char *szBuffering) ;BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer) {FILE *fp = fopen("e:\\www\\cgi-bin\\log.txt", "rw");if (fp) {fprintf(fp, "hello");fclose(fp);} pVer->dwExtensionVersion = MAKELONG(HSE_VERSION_MINOR, HSE_VERSION_MAJOR);lstrcpyn((LPSTR) pVer->lpszExtensionDesc, "ISAPI Tester", HSE_MAX_EXT_DLL_NAME_LEN);return TRUE; }DWORD WINAPI HttpExtensionProc(IN EXTENSION_CONTROL_BLOCK *pECB) {DWORD hseStatus; DWORD msecDelay; char *pszBuffering;pszBuffering = "default (on)"; msecDelay=25;if ( (char)*(pECB->lpszQueryString) != '\0' ){ pszBuffering="off";pECB->ServerSupportFunction (pECB->ConnID, HSE_REQ_SET_FLUSH_FLAG, (LPVOID) TRUE, NULL, NULL ); } hseStatus = SendOutputToClient(pECB, msecDelay, pszBuffering);return hseStatus; }BOOL WINAPI TerminateExtension(IN DWORD dwFlags) { return TRUE; }DWORD SendHeaderToClient(IN EXTENSION_CONTROL_BLOCK *pecb, IN LPCSTR pszErrorMsg) { HSE_SEND_HEADER_EX_INFO SendHeaderExInfo; char szStatus[] = "200 OK"; char szHeader[1024];wsprintf(szHeader, "Content-Type: text/plain\r\n\r\n");SendHeaderExInfo.pszStatus = szStatus; SendHeaderExInfo.pszHeader = szHeader; SendHeaderExInfo.cchStatus = lstrlen(szStatus); SendHeaderExInfo.cchHeader = lstrlen(szHeader); SendHeaderExInfo.fKeepConn = FALSE;if (!pecb->ServerSupportFunction(pecb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, &SendHeaderExInfo, NULL, NULL))return HSE_STATUS_ERROR;return HSE_STATUS_SUCCESS; }DWORD SendOutput(IN EXTENSION_CONTROL_BLOCK *pecb, IN DWORD msecDelay) {CHAR pchOutput[1024]; DWORD hseStatus = HSE_STATUS_SUCCESS; int i; DWORD len;for( i=0; i < 10 ; i++ ) { len = wsprintfA(pchOutput, "WriteClient output %d\n", i); if ( !pecb->WriteClient(pecb->ConnID, pchOutput, &len, HSE_IO_SYNC) ){ hseStatus = HSE_STATUS_ERROR; break; } Sleep(msecDelay); } return hseStatus; }DWORD SendOutputToClient(IN EXTENSION_CONTROL_BLOCK *pecb, IN DWORD msecDelay, char *szBuffering) { CHAR pchBuffer[1024]; DWORD hseStatus = HSE_STATUS_SUCCESS;wsprintfA(pchBuffer, "WriteClient buffering %s", szBuffering);hseStatus = SendHeaderToClient(pecb, pchBuffer);if (hseStatus == HSE_STATUS_SUCCESS) {hseStatus = SendOutput(pecb, msecDelay );if (hseStatus != HSE_STATUS_SUCCESS) {wsprintfA(pchBuffer, "Send Failed: Error (%d)<\br>", GetLastError()); SendHeaderToClient(pecb, pchBuffer); } }pecb->ServerSupportFunction( pecb->ConnID, HSE_REQ_DONE_WITH_SESSION, NULL, NULL, NULL);return (hseStatus); }
5,工程根目錄下新建test.def文件

LIBRARY "test" EXPORTSGetExtensionVersionHttpExtensionProcTerminateExtension
6,菜單點擊Project - Properties...

Build targets 選項卡里,右邊大概中間位置的output filename將bin\debug\libtest.dll改為bin\debug\test.dll,然后Release版本的也這樣改

左邊中下位置,點擊Build options,彈出窗口

新窗口的左邊列表框里選中工程名,這樣debug和release版本都能用同樣的編譯選項了。

Compiler settings 選項卡里,Compiler flags子選項卡中,Target組里面選中.DLL executable (-tWD)和32-bit multi-threaded (-tWM)

Linker settings 選項卡里,Link libraries里,添加user32,添加kernel32,添加import32,添加cw32mt,cw32mt是靜態鏈接庫,cw32mti是動態鏈接庫,需要BCC的dll文件才行,所以我選擇了cw32mt,將包含的函數編譯進工程里,但這樣遠遠還不夠,還需要obj支持

于是other linker options里面,添加

-Gi c0d32.obj

這個是動態鏈接庫支持文件,沒有它cw32mt里有兩個函數就無法連接,但在工程里如果取消標準庫里的一些函數,比如strcpy、strlen,cw32mt就可以不用,但是dll文件會在IIS里奔潰,同時將IIS程序池也搞奔潰掉,我擺渡了很久才找到這個選項

最后,Custom variables選項卡里,添加key = def_input,value = test.def,這樣開始在Link object files to dynamic library的宏里面設置的$def_input就有了實例

OK - OK,保存設置

7,Ctrl + F9,工程進行Build,在bin\debug或者bin\release目錄下就生成了test.dll,將test.dll放入IIS里設置的可執行目錄下,就能運行看到結果了。

——————追加:第二天繼續MinGW編譯ISAPI的測試——————

因為機器里已經安裝了Cygwin和MSYS2,所以首先用Cygwin里的gcc編譯項目,gcc版本6.40,編譯項目成功,但是用VS的dumpbin -exports dll文件卻找不到函數地址

于是使用MSYS2,并在MSYS2模擬器中安裝了gcc 7.2,編譯 項目成功,同樣dumpbin找不到函數地址

dumpbin是VS的dll工具,就是說它能找到地址,那么IIS同樣也能找到地址,它找不到IIS也找不到,所以在IIS中,ISAPI擴展會返回500錯誤

這個問題把我折騰慘了,最后鬼使神差下載了單獨版本的MinGW,安裝完GCC后,編譯項目成功,用dumpbin也能找到函數地址

于是對比了一下,發現GCC線程模式不一樣,Cygwin和MSYS2里的gcc都是posix線程,而MinGW里的卻是win32線程,所以能用,總算吸取了教訓,漲了點姿勢。

命令行編譯

gcc -c test.c dllwrap --def test.def -o test.dll test.o dumpbin -exports test.dll

如果是用CodeBlocks,那么還是要更改一下配置

Settings-Compiler,選擇GNU GCC Compiler,Other settings-Advanced options
Commands 選項卡里,Command選擇Link object files to dynamic library,Command line macro里將宏改一下,在$exe_output后面添加一個$def_input變量
原宏:$linker -shared -Wl,--output-def=$def_output -Wl,--out-implib=$static_output -Wl,--dll $libdirs $link_objects $link_resobjects -o $exe_output $link_options $libs
現宏:$linker -shared -Wl,--output-def=$def_output -Wl,--out-implib=$static_output -Wl,--dll $libdirs $link_objects $link_resobjects -o $exe_output $def_input $link_options $libs
因為IDE默認是g++最終生成DLL,所以不知為何會帶上一個動態鏈接庫,使用dumpbin查看,是一個名為libgcc_s_dw2-1.dll的東東,而且附帶兩個函數:
25 ?__deregister_frame_info
6A ?__register_frame_info
于是Git-bash進入${MINGW_LIB},運行
grep -iaR "__deregister_frame_info" .
最終找到是${MINGW_LIB}/gcc/mingw32/6.3.0/libgcc_eh.a這個文件所持有的函數
于是點擊Project - Build options,選中工程名,Linker settings的Other linker options里添加-static-libgcc
重新編譯工程,dumpbin發現,libgcc_s_dw2-1.dll不見了,好了,就這樣吧,寫完手工。

總結

以上是生活随笔為你收集整理的BCC(Borland C++ Compiler)编译 ISAPI 扩展或者用MinGW也行的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。