可用MinGW編譯的win32繪圖框架
鑑於Microsoft Visual Studio體積巨大,我堅持不願意安裝,故在windows下程式設計一直都用MinGW和TCC作為編譯器,用Codebocks作為開發環境。MinGW對於C/C++標準庫支援很好,但是對於windows API就沒那麼好了。由於windows家族從win32API-> MFC->WPF->.net,體積龐大演變複雜,第三方庫顯然無法承載。
對於我個人工作,console下的操作使用標準庫函式已經足夠,檔案操作使用.bat批處理,網路操作使用Python,唯一需要win32系統函式的地方就是圖形介面了。這次在編寫botzone的貪吃蛇程式時,平臺規定用cpp+jsoncpp,為了方便除錯,只好使用MinGW呼叫win32API庫做一個簡單的繪圖框架。
由於GDI庫過於底層,使用起來很龐雜,我的思路是寫一個固定的框架程式碼,每隔30ms顯示某記憶體中的固定圖片(別忘了加鎖),其他所有的繪製過程都歸結到對於圖片的圖形繪製上去。這樣最大限度地隔離了win32系統。
首先建立基本的主入口和訊息迴圈函式WinMain:
#include <windows.h>
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Double Snake Game Simulator", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
800, /* The programs width */
600, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
訊息處理函式
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_TIMER:
RedrawWindow(hwnd,NULL,NULL,RDW_ERASE|RDW_INVALIDATE);
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
RECT r;
GetClientRect(hwnd,&r);
EnterCriticalSection(&displock);
hdc=BeginPaint(hwnd,&ps);
DrawText(hdc,"Hello world",-1,&r,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hwnd,&ps);
LeaveCriticalSection(&displock);
printf("Paint%d!\n",num);
break;
}
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
為了不斷重繪,建立定時器
UINT_PTR WINAPI SetTimer(
_In_opt_ HWND hWnd, //視窗控制代碼
_In_ UINT_PTR nIDEvent, //定時器ID 使用者指定
_In_ UINT uElapse, //定時時間ms
_In_opt_ TIMERPROC lpTimerFunc //回撥函式 NULL則送入訊息迴圈
);
若在新建定時器時指定了nIDEvent,則可在訊息迴圈中判斷wParam的取值來區分定時器訊息源。本程式沒有用到這一特性。本程式程式碼為:
SetTimer(hwnd,1,20,NULL);
並在訊息處理中新增一行
case WM_TIMER:
//定時器操作
重繪視窗使用
BOOL WINAPI RedrawWindow(
HWND hwnd, //視窗控制代碼
CONST RECT* lprcUpdate, //重繪區域
HRGN hrgnUpdate, //重繪區域,優先
UINT flags //重繪標誌位
);
標誌位的設定大有講究。Win32的重繪概念比較複雜,將視窗標為invalid和生成WM_PAINT訊息是兩個過程,此外還有WM_ERASEBKGND訊息作為前導。
本程式中使用
RedrawWindow(hwnd,NULL,NULL,RDW_ERASE|RDW_INVALIDATE)
RedrawWindow(hwnd,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW)
結果一樣。但是如果漏掉了前兩個引數,則WM_PAINT訊息仍會產生並執行相應重繪程式碼,但重繪後窗口介面不會更新,只有最小化或被遮擋後才行。
建立執行緒使用
HANDLE WINAPI CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes=NULL,
_In_ SIZE_T dwStackSize=0,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ LPVOID lpParameter=NULL,
_In_ DWORD dwCreationFlags=0,
_Out_opt_ LPDWORD lpThreadId=NULL
);
若呼叫了C庫函式,則應使用
uintptr_t _beginthread( // NATIVE CODE
void( __cdecl *start_address )( void * ),
unsigned stack_size,
void *arglist
);
本程式中,我使用
_beginthread(ThreadFunction,0,NULL);
其中執行函式ThreadFunction形式為
void ThreadFunction(void* pParam)
{
//running code
}
退出執行緒使用
ExitThread();
_endthread();
建立臨界區使用
CRITICAL_SECTION displock;
初始化
InitializeCriticalSection(&displock);
進入臨界區
EnterCriticalSection(&displock);
離開臨界區
LeaveCriticalSection(&displock);
釋放資源
DeleteCriticalSection(&displock);
在WM_PAINT中:
- 清除背景
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW));
- 選擇畫筆(用於畫線)
HPEN hBluePen = CreatePen(PS_SOLID, 1, RGB(200, 0, 80)); //筆型 粗細 顏色
HPEN hOldPen = (HPEN)SelectObject(hdc, hBluePen); //返回老畫筆
/********使用畫筆**********/
SelectObject(hdc, hOldPen); //設定回原畫筆
DeleteObject(hBluePen); //釋放資源
- 選擇畫刷(用於填充)
HBRUSH hPurpleBrush = CreateSolidBrush(RGB(255, 0, 255));
/********使用畫刷***********/
FillRect(hdc, &lprc, hPurpleBrush);
DeleteObject(hPurpleBrush);
畫線
hdc = BeginPaint(hWnd, &ps);
MoveToEx(hdc, 60, 20, NULL);
LineTo(hdc, 264, 122);
EndPaint(hWnd, &ps);
折線
BOOL Polyline(HDC hdc, CONST POINT *lppt, int cPoints);
POINT Pt[7];
Pt[0].x = 20; Pt[0].y = 50;
Pt[1].x = 180; Pt[1].y = 50;
Pt[2].x = 180; Pt[2].y = 20;
hdc = BeginPaint(hWnd, &ps);
Polyline(hdc, Pt, 3);
EndPaint(hWnd, &ps);
繪製矩形
PAINTSTRUCT ps;
HDC hdc;
RECT lprc;
//GetClientRect(hwnd,&lprc); 獲取視窗矩形大小
SetRect(&lprc,1,1,800,600); //left up right down
hdc=BeginPaint(hwnd,&ps);
FillRect(hdc, &lprc, (HBRUSH) (1));
EndPaint(hwnd,&ps);
繪製記憶體中的圖片
需要使用Bitmap,概念也比較複雜。Bitmap可分為裝置無關DIB和裝置相關DDB兩種,DDB是和dc相關的點陣圖,不同情況下用CreateBMP(),CreateCompatibleBMP(),LoadBMP(),LoadImage()等建立的就是DDB。DIB就是一片記憶體,裡面儲存著點陣圖掐頭去尾,只留下RGB,或者畫素+色板的資訊。
Bitmap屬於一種GDI物件,同Brushes Fonts Paths Pens Regions等物件一樣,可以被指定到GDI目標裝置context上。
以下函式從影象畫素矩陣建立DDB控制代碼
HBITMAP CreateBitmap(
_In_ int nWidth, //點陣圖寬度
_In_ int nHeight, //點陣圖高度
_In_ UINT cPlanes, //該裝置使用的顏色位面數目
_In_ UINT cBitsPerPel, //點顏色位數
_In_ const VOID *lpvBits //資料指標
);
對於彩色影象,用以下函式不需要型別轉換步驟,速度更快:
HBITMAP CreateCompatibleBitmap(HDC hdc,int nWidth,int nHeight);
為了防止螢幕閃爍,新建DC上下文應用雙緩衝機制。
HDC CreateCompatibleDC(
HDC hdc
);
將DC與Bitmap繫結
HDC memdc=CreateCompatibleDC(hdc);
HBITMAP memBmp=CreateCompatibleBitmap(hdc,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
SelectObject(memdc,memBmp);
將緩衝區資料複製到DIB
int SetDIBits(
_In_ HDC hdc, //裝置控制代碼
_In_ HBITMAP hbmp, //點陣圖控制代碼
_In_ UINT uStartScan, //開始行=0
_In_ UINT cScanLines, //行數
_In_ const VOID *lpvBits, //畫素資料陣列
_In_ const BITMAPINFO *lpbmi, //指向DIB資訊的資料結構
_In_ UINT fuColorUse=DIB_RGB_COLORS
);
從DIB複製到緩衝區資料.
若lpvBits=NULL且BITMAPINFO中的biBitCount成員被初始化為零,binfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER),則當前顯示裝置屬性將被輸出。
int GetDIBits(
_In_ HDC hdc,
_In_ HBITMAP hbmp,
_In_ UINT uStartScan,
_In_ UINT cScanLines,
_Out_ LPVOID lpvBits,
_Inout_ LPBITMAPINFO lpbi,
_In_ UINT uUsage
);
其中,BITMAPINFO定義了DIB的維度和顏色資訊
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
typedef struct tagBITMAPINFOHEADER {
DWORD biSize; //自身大小
LONG biWidth; //寬度
LONG biHeight; //高度
WORD biPlanes=1;
WORD biBitCount; //位深度
DWORD biCompression; //壓縮方式 一般BI_RGB
DWORD biSizeImage; //假如不是BI_JPEG或BI_PNG,設為0即可
LONG biXPelsPerMeter; //畫素密度
LONG biYPelsPerMeter; //畫素密度
DWORD biClrUsed=0;
DWORD biClrImportant=0;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
以下是繪製圖片的程式碼
HDC memdc=CreateCompatibleDC(hdc);
HBITMAP memBmp=CreateCompatibleBitmap(hdc,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
SelectObject(memdc,memBmp);
BITMAPINFO binfo;
ZeroMemory(&binfo,sizeof(BITMAPINFO));
binfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
binfo.bmiHeader.biBitCount=32;
binfo.bmiHeader.biCompression=0;
binfo.bmiHeader.biWidth=SCREEN_W;
binfo.bmiHeader.biHeight=SCREEN_H;
binfo.bmiHeader.biPlanes=1;
binfo.bmiHeader.biSizeImage=0;
BYTE *pBuf=new BYTE[SCREEN_H*SCREEN_W*4];
int row_size=SCREEN_W*4;
for(int i=0;i<SCREEN_H;i++)
pBuf[i*row_size+i*4]=200;
SetDIBits(memdc,memBmp,0,
binfo.bmiHeader.biHeight,
pBuf,(BITMAPINFO*)&binfo,
DIB_RGB_COLORS);
BitBlt(hdc, 0, 0, binfo.bmiHeader.biHeight, binfo.bmiHeader.biWidth,memdc, 0, 0, SRCCOPY);
DeleteDC(memdc);
DeleteObject(memBmp);
按照以上程式碼執行,發現重繪閃爍嚴重。這個網站給出了全面的解決辦法。
主要問題在於windows的重繪分為兩個階段
- WM_ERASEBKGND訊息:清除背景
- WM_PAINT: 繪製新內容
這樣,在響應兩個訊息之間的間隔,螢幕為白板,從而發生閃爍。解決方法有以下兩種:
- 在WM_ERASEBKGND響應程式碼中返回非零值
case WM_ERASEBKGND:
return 1;
- 將視窗的背景刷設為NULL
wincl.hbrBackground=0;
此外,當繪製物件過多時,必須新增雙緩衝,否則將可見影象重新整理過程。典型的雙緩衝過程如下:
HDC hdcMem;
HBITMAP hbmMem;
HANDLE hOld;
PAINTSTRUCT ps;
HDC hdc;
....
case WM_PAINT:
// Get DC for window
hdc = BeginPaint(hwnd, &ps);
// Create an off-screen DC for double-buffering
hdcMem = CreateCompatibleDC(hdc);
hbmMem = CreateCompatibleBitmap(hdc, win_width, win_height);
hOld = SelectObject(hdcMem, hbmMem);
/*********Draw into hdcMem here*************/
/*********Draw into hdcMem here*************/
// Transfer the off-screen DC to the screen
BitBlt(hdc, 0, 0, win_width, win_height, hdcMem, 0, 0, SRCCOPY);
// Free-up the off-screen DC
SelectObject(hdcMem, hOld);
DeleteObject(hbmMem);
DeleteDC (hdcMem);
EndPaint(hwnd, &ps);
至此基本解決了閃爍問題
鍵盤相應
case WM_KEYDOWN:
switch (wParam)
{
case VK_UP:
SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0);
break;
case VK_DOWN:
SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);
break;
case VK_LEFT:
SendMessage(hwnd, WM_HSCROLL, SB_PAGEUP, 0);
break;
case VK_RIGHT:
SendMessage(hwnd, WM_HSCROLL, SB_PAGEDOWN, 0);
break;
}
break;
以下是總體程式碼
BYTE *pBuf=new BYTE[SCREEN_H*SCREEN_W*4];
int row_size=SCREEN_W*4;
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_CREATE:
ZeroMemory(pBuf,SCREEN_H*SCREEN_W*4);
for(int i=0;i<SCREEN_H;i++)
pBuf[i*row_size+i*4]=200;
break;
case WM_TIMER:
RedrawWindow(hwnd,NULL,NULL,RDW_ERASE|RDW_INVALIDATE);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
RECT lprc;
EnterCriticalSection(&displock);
hdc=BeginPaint(hwnd,&ps);
//清除背景
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW));
HPEN hBluePen = CreatePen(PS_SOLID, 10, RGB(200, 0, 80));
HPEN hPen = (HPEN)SelectObject(hdc, hBluePen);
MoveToEx(hdc, 100, 100, NULL);
LineTo(hdc, num, 2*num);
SelectObject(hdc, hPen);
DeleteObject(hBluePen);
HBRUSH hPurpleBrush = CreateSolidBrush(RGB(255-num, num, 20));
SetRect(&lprc,600,400,650,450);
FillRect(hdc, &lprc, hPurpleBrush);
DeleteObject(hPurpleBrush);
//checkScreenProperty(hdc);
HDC memdc=CreateCompatibleDC(hdc);
HBITMAP memBmp=CreateCompatibleBitmap(hdc,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
SelectObject(memdc,memBmp);
BITMAPINFO binfo;
ZeroMemory(&binfo,sizeof(BITMAPINFO));
binfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
binfo.bmiHeader.biBitCount=32;
binfo.bmiHeader.biCompression=0;
binfo.bmiHeader.biWidth=SCREEN_W;
binfo.bmiHeader.biHeight=SCREEN_H;
binfo.bmiHeader.biPlanes=1;
binfo.bmiHeader.biSizeImage=0;
SetDIBits(memdc,memBmp,0,
binfo.bmiHeader.biHeight,
pBuf,(BITMAPINFO*)&binfo,
DIB_RGB_COLORS);
BitBlt(hdc, 0, 0, binfo.bmiHeader.biWidth, binfo.bmiHeader.biHeight,memdc, 0, 0, SRCCOPY);
DeleteDC(memdc);
DeleteObject(memBmp);
GetClientRect(hwnd,&lprc);
DrawText(hdc,"Hello World",-1,&lprc,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hwnd,&ps);
LeaveCriticalSection(&displock);
break;
}
case WM_DESTROY:
running=false;
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
總結與吐槽
微軟網頁上的這段典型程式碼體現出GDI有多麼冗繁而反人類。
由於從一開始就沒有面向物件的概念,所以各種變數資料裸露在外,大量名稱交錯使用,很容易造成混亂。給程式設計師的記憶負擔也很重。
相關推薦
可用MinGW編譯的win32繪圖框架
鑑於Microsoft Visual Studio體積巨大,我堅持不願意安裝,故在windows下程式設計一直都用MinGW和TCC作為編譯器,用Codebocks作為開發環境。MinGW對於C/C++標準庫支援很好,但是對於windows API就沒那麼好了。
用MinGW編譯Win32 GDI應用程式
用來編譯的批處理 del *.o gcc -c *.cpp -Wno-write-strings windres Resource.rc Resource.o g++ *.o -o Gomoku.exe -s -lgdi32 -luser32 -lkern
mp4v2使用mingw編譯配置
dllexport win32 cygwin col back dll amp import 部分 備註:黃色部分為原始語句,紅色部分為修改後的語句 ‘-’表示去掉,‘+’表示增加 1.修改configure文件 1)去掉enable_shared=no *-*-mi
[X264] MinGW編譯x264,VC中調用libx264.dll-------------<參考轉>
-1 bin文件 source color turn 9.4 make int lease 1. 下載並按照MinGW,最好就缺省按照 http://sourceforge.net/projects/ ... ler/mingw-get-inst/ 把C:\Mi
Win32程序框架
post show nts zcl nap pda wndproc sna char #include<Windows.h> LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM); int WINAPI
iOS繪圖框架CoreGraphics分析
png 保存 alloc opengl-es div 運行 dell .html shc 由於CoreGraphics框架有太多的API,對於初次接觸或者對該框架不是十分了解的人,在繪圖時,對API的選擇會感到有些迷茫,甚至會覺得iOS的圖形繪制有些繁瑣。因此,本文主要介紹
MinGW 編譯 libaom 1.0.0 註意事項
bsp lib class fig har 註意事項 pre ble nor CMake 後不生成 config/aom_version.h 文件 需要手動編寫 #define VERSION_MAJOR 1 #define VERSION_MINOR 0 #define
Clion使用MinGW編譯好的boost庫
party uil roo con build nat 命令行 dha -s MinGW編譯Boost庫可以參考我之前寫的編譯Boost的文章。 以下是cmake鏈接boost靜態庫的配置: 1 cmake_minimum_required(VERSION 3.8)
Windows使用mingw編譯openblas
系統環境:win10 軟體環境: (1)mingw 5.3,使用Qt5.11.1自帶的 (2)OpenBLAS-0.2.20 (3)Armadillo9.1 幾點說明: (1)關於openblas在window下的使用多是介紹其window的預編譯版,使用VS編譯器,但筆者強迫症嚴重
關於mingw編譯Qt時無法編譯opengl es2(ANGLE)版本的問題
最近在使用mingw64(gcc 8.1.0)編譯Qt5.12.0時,發現config總是檢測opengl es2不通過,雖然可以使用opengl desktop,但根據qt官方的建議,如果不直接使用opengl函式,還是使用opengl es2版本相容性更好,而且opengl es2和qt自帶
QT中使用MinGW 編譯的protobuf庫--包含庫的生成和使用
0前言 最近要在QT中使用protobuf,於是需要編譯protobuf靜態庫檔案,匯入qt使用,沒想到過程非常曲折,各種報錯各種坑,在網上參考了很多文章,最後終於成功了,現在將QT中使用protobuf的整個配置過程都寫出來提供給大家,希望能夠幫助到大家。
用mingw編譯ffmpeg
一、安裝mingw 二、下載ffmpeg 去官網下ffmpeg原始碼tar包 三、 編譯ffmpeg 執行mingw指令碼“msys.bat”進入shell,路徑為: C:\MinGW\msys\1.0 下載yasm的windows版本編
QT5.10開發(2) 在Windows 10下使用MinGW編譯 靜態Qt 5.10 release版 詳細過程
Qt建議安裝動態連結Dbug版和編譯安裝靜態連結release版前提: 先安裝動態連結Dbug版,方法:QT5.10開發(1)安裝QT5.10 地址:http://blog.csdn.net/qq_15304853/article/details/79165301 然後編譯
【POCO】POCO學習總結(四)——MinGW編譯poco
在window下使用MinGW編譯poco 使用MSYS 下載MSYS 安裝 執行mingw-get-setup.exe,只選擇安裝msys-base(mingw我使用Qt中自帶的) 配置 開啟C:\MinGW\msys\1.0\ms
MinGW編譯c++,中文顯示亂碼解決方案
我比較喜歡MinGW,現在使用的是 C:\WINDOWS\system32>gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_
Windows環境下使用minGW編譯boost庫(windows下編譯使用asio, thread等)
我在windows下沒有用vs進行開發, 而是安裝mingw+eclipse. 根據官網介紹, boost庫中, 一些庫無需編譯即可使用, 而有一些類庫, 如 asio, thread都是與平臺有關的, 所以需要編譯後才能使用. 根據官網想到, 在linux下面編譯安裝
使用 MinGW 編譯 ZeroMQ 靜態庫
最近折騰zeromq,嘗試用 MinGW 來編譯了一下。 根據 http://zeromq.org/build:mingw 的說明,用MinGW來編譯 ZeroMQ 自然是沒有問題的。但是業餘測試一些簡單的程式碼還是用靜態庫比較方便。怎奈何,預設的 configure
mingw編譯librtmp
1 下載 MinGW和MSYS:http://www.mingw.org/ zlib:http://www.zlib.net/ openSSL:http://www.openssl.org/ ActiveState Perl:http://www.perl.org/ rt
mingw 編譯opencv
使用MinGW編譯OpenCV庫 系統環境與資源 MinGW編譯器目錄:TDM-GCC版,位於D:\complicer\MinGW OpenCV原始碼目錄:D:\mysoftware\opensource\opencv OpenCV
Linphone 3.7.0 for mingw 編譯安裝
前言 接著講這個,前面在mingw上成功編譯了linphone 3.5.2版本,執行基本都沒發現有問題。後面就開始編譯最新版本linphone,編譯這個第一步是必須獨自編譯安裝belle-sip 1.3.0,編譯這個必須先編譯安裝antlr 相應版本(官方文件寫的