自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用Cygwin在Windows上進(jìn)行Unix開發(fā)

原創(chuàng)
開發(fā) 開發(fā)工具
本文主要向讀者介紹如何在Cygwin下進(jìn)行程序開發(fā)。文章將首先介紹使用GCC開發(fā)控制臺模式的應(yīng)用程序和GUI模式的應(yīng)用程序,然后闡述在Cygwin下如何調(diào)試程序,隨后詳細(xì)講解在Cygwin下動態(tài)鏈接庫的構(gòu)建和使用,最后介紹資源文件的有關(guān)知識。

一、Cygwin簡介

Cygwin是許多自由軟件的集合,最初由Cygnus Solutions開發(fā),用于各種版本的Microsoft Windows上,運行UNIX類系統(tǒng)。Cygwin的主要目的是通過重新編譯,將POSIX系統(tǒng)(例如Linux、BSD,以及其他Unix系統(tǒng))上的軟件移植到Windows上。Cygwin包括了一套庫,該庫在Win32系統(tǒng)下實現(xiàn)了POSIX系統(tǒng)調(diào)用的API;還有一套GNU開發(fā)工具集(比如GCC、GDB),這樣可以進(jìn)行簡單的軟件開發(fā);還有一些UNIX系統(tǒng)下的常見程序。2001年,新增了X Window System。另外還有一個名為MinGW的庫,可以跟Windows本地的MSVCRT庫(Windows API)一起工作。

二、在Cygwin中使用GCC

下面我們開始介紹如何在Cygwin中使用GCC開發(fā)控制臺模式的應(yīng)用程序和GUI模式的應(yīng)用程序。

控制臺模式的應(yīng)用程序

使用gcc編譯程序跟在UNIX操作系統(tǒng)之下非常相似,關(guān)于gcc的標(biāo)準(zhǔn)用法和選項可以參考其用戶手冊。下面是一個簡單的示例:

例1:利用GCC構(gòu)建Hello World

C:\> gcc hello.c -o hello.exe
C:\> hello.exe
Hello, World

C:\>

GUI模式的應(yīng)用程序

Cygwin使我們可以編譯出能夠訪問所有標(biāo)準(zhǔn)Windows32位API的程序,其中包括定義在微軟公司和暢銷出版物中的那些GUI函數(shù)。然而,使用GNU工具跟使用微軟公司的工具構(gòu)建應(yīng)用程序的過程會稍有不同。絕大多數(shù)情況下,根本無需修改源代碼。然而,您應(yīng)該刪除函數(shù)中的全部__export屬性,并將其換成下面的內(nèi)容:

int foo (int) __attribute__ ((__dllexport__));

int
foo (int i)

Cygwin Makefile與其他任何類UNIX的Makefile非常類似,唯一區(qū)別在于我們需要使用gcc -mwindows來把程序連接成一個圖形用戶界面應(yīng)用程序,而非命令行應(yīng)用程序。下面是一個例子:

myapp.exe : myapp.o myapp.res
	gcc -mwindows myapp.o myapp.res -o $@

myapp.res : myapp.rc resource.h
	windres $< -O coff -o $@

注意,通過利用windres可把Windows資源編譯成一個COFF格式的.res文件,這樣就能把您需要的所有位圖、圖標(biāo)及其他資源放到一個目標(biāo)文件中。 正常情況下,如果您省略了“-O coff”的話,它就會創(chuàng)建一個Windows格式的文件,但是我們只能鏈接COFF格式的目標(biāo)文件。所以,我們吩咐windres生成COFF格式的目標(biāo)文件。我們的大部分示例都假定你的鏈接程序能夠直接處理Windows的資源文件,我們保留.res的命名約定。關(guān)于windres的更多信息請參見有關(guān)手冊。下面是一個GUI模式入門之用的“Hello ,World !”程序:

/*-------------------------------------------------*/
/* hellogui.c :一個圖形模式的hello world程序                    */
/*編譯命令:gcc -mwindows hellogui.c -o hellogui.exe */
/*-------------------------------------------------*/
#include <windows.h>

char glpszText[1024];

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance, 
		HINSTANCE hPrevInstance,
		LPSTR lpCmdLine,
		int nCmdShow)
{
	sprintf(glpszText, 
		"Hello World\nGetCommandLine(): [%s]\n"
		"WinMain lpCmdLine: [%s]\n",
		lpCmdLine, GetCommandLine() );

	WNDCLASSEX wcex; 
 
	wcex.cbSize = sizeof(wcex);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = "HELLO";
	wcex.hIconSm = NULL;

	if (!RegisterClassEx(&wcex))
		return FALSE; 

	HWND hWnd;
	hWnd = CreateWindow("HELLO", "Hello", WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

	if (!hWnd)
		return FALSE;

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	
	switch (message) 
	{
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			RECT rt;
			GetClientRect(hWnd, &rt);
			DrawText(hdc, glpszText, strlen(glpszText), &rt, DT_TOP | DT_LEFT);
			EndPaint(hWnd, &ps);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

#p#

三、調(diào)試Cygwin程序

如果您的程序無法正常運行,通常情況下是由于其中的bug所致,因為程序本身存在錯誤會導(dǎo)致出乎意料的結(jié)果甚至崩潰。借助于一種稱為調(diào)試器的專用工具可以使得查找和修正錯誤變得更簡單一些。就Cygwin而論,其調(diào)試器是GDB,即GNU debugger的縮寫。這個工具使我們可以在一個受控環(huán)境中運行我們的程序,在這個環(huán)境中,我們可以考察程序運行過程中或其崩潰之后的狀態(tài)。有時候,程序崩潰時操作系統(tǒng)就會把程序當(dāng)?shù)魰r的內(nèi)存內(nèi)容轉(zhuǎn)儲出來,現(xiàn)在通常是寫在一個叫core 的file 里面。在Cygwin中,這些文件通常是些常規(guī)的文本文件,所以無法直接為GDB所用。

在調(diào)試程序之前,需要對需要進(jìn)行調(diào)試的程序做一些準(zhǔn)備工作,具體來說,就是在把源程序編譯成目標(biāo)程序的時候為所有標(biāo)志添加-g。

例2:利用-g進(jìn)行編譯

$ gcc -g -O2 -c myapp.c
$ gcc -g myapp.c -o myapp

這樣就會在生產(chǎn)的目標(biāo)文件中加入額外的信息來告知調(diào)試器有關(guān)行號、變量名及其他有用的信息,不過這會使得目標(biāo)文件的尺寸驟增。這些額外的符號和調(diào)試信息提供了原始代碼的足夠信息,所以調(diào)試器在調(diào)試它們的時候會更加容易。

在Windows版本的GNUPro中,GDB具有一個全功能的圖形界面。在Cygwin的Net發(fā)行版本中,GDB只能在命令行下使用。要調(diào)用GDB,只需在命令提示符下輸入gdb myapp.exe即可。這時會顯示一些您自己的有關(guān)文本信息,之后GDB會提示您繼續(xù)輸入其他命令。只要看到這個提示符,就表示gdb正在等待您輸入命令,如果您鍵入help命令,那么就會收到您可以使用的各個命令的幫助信息,當(dāng)然您也可以通過閱讀“GDB User's Manual”來全面細(xì)致地了解gdb及其使用方法。

如果你的程序崩潰了,并且您想弄清它為什么崩潰的話,最好的辦法是鍵入run來運行您的程序。等它崩潰之后,您可以鍵入where命令來看看它在哪里崩潰的,或者輸入info locals命令來查看所有局部變量的值。此外,如果鍵入print命令的話,我們還可以檢查單獨的變量以及指向這些變量的指針。

如果您的程序做了出乎意料之外的事情,那么可以使用break命令讓gdb在程序到達(dá)指定的函數(shù)或者行號的時候停止程序的運行:

例3:gdb中的中斷命令

(gdb) break my_function
(gdb) break 47

現(xiàn)在,當(dāng)我們輸入run命令之后,我們的程序會在斷點處停下來,這樣我們就能使用其他的gdb命令來查看程序當(dāng)時的狀態(tài)、修改變量以及單步調(diào)試程序的各個語句。需要注意的是,我們可以給run命令附加其他的參數(shù),以便向我們的程序提供相應(yīng)的命令行參數(shù)。例如,下面的兩條命令的效果是一樣的:

例4:利用命令行參數(shù)進(jìn)行調(diào)試

$ myprog -t foo --queue 47

$ gdb myprog
(gdb) run -t foo --queue 47

#p#

四、動態(tài)鏈接庫的構(gòu)建和使用

動態(tài)鏈接庫(DLL)是指在程序運行時而非編譯時鏈接進(jìn)我們的程序的那些庫。一個動態(tài)鏈接庫有三部分組成:

◆導(dǎo)出表

◆代碼和數(shù)據(jù)

◆導(dǎo)入庫

代碼和數(shù)據(jù)是我們需要編寫的函數(shù)、變量等內(nèi)容,它們將被合并到一起放入dll,你可以簡單的理解成建立了一個碩大的目標(biāo)文件。但是它們卻不會放入您的.exe文件。導(dǎo)出表含有動態(tài)庫為其他程序提供給的函數(shù)和變量,可以簡單的理解成這是一個“全局”符號表,除此之外的內(nèi)容都是不可見的。通常情況下,我們需要利用文本編輯程序手工建立該表,不過我們也可以利用代碼中的函數(shù)表來自動生成這個導(dǎo)出表。dlltool程序可以根據(jù)導(dǎo)出符號組成的文本文件來創(chuàng)建動態(tài)鏈接庫的導(dǎo)出部分。輸入庫類似于類UNIX系統(tǒng)中的.a程序庫,但是它只包含通知操作系統(tǒng)應(yīng)用程序跟dll交互方式(即導(dǎo)入方法)所需信息。這些信息可以鏈接到我們的.exe程序中。當(dāng)然這些信息也可以利用dlltool程序來建立。

構(gòu)建動態(tài)鏈接庫

我們這里將簡單介紹如何利用gcc來建立動態(tài)鏈接庫,有關(guān)gcc建立動態(tài)庫的更詳盡的選項,可以參考gcc的有關(guān)文檔。首先提供一個簡單的示例來演示建立一個動態(tài)鏈接庫的過程。本例中,我們的程序(myprog.exe) 由單個源文件myprog.c組成,而動態(tài)鏈接庫(mydll.dll)的內(nèi)容則由稱為mydll.c的文件得到。

幸運的是,在最新的gcc和binutils的幫助下,建立動態(tài)鏈接庫的過程非常簡單。下面我們介紹編譯mydll.c的具體過程。

#include <stdio.h>

int
hello()
{
  printf ("Hello World!\n");
}  

首先將mydll.c編譯為目標(biāo)代碼,命令如下所示:

gcc -c mydll.c

然后,告訴gcc我們要構(gòu)建一個共享庫,命令如下所示:

gcc -shared -o mydll.dll mydll.o

就這么簡單!現(xiàn)在,我們將這個動態(tài)鏈接庫鏈接到一個簡單程序上,程序代碼如下所示:

int 
main ()
{
  hello ();
}

現(xiàn)在我們用下列命令來連接動態(tài)鏈接庫,命令如下所示:

gcc -o myprog myprog.c -L./ -lmydll

然而,如果想要把動態(tài)鏈接庫做成一個導(dǎo)出庫的話,可以使用下列語法:

gcc -shared -o cyg${module}.dll \

-Wl,--out-implib=lib${module}.dll.a \

-Wl,--export-all-symbols \

-Wl,--enable-auto-import \

-Wl,--whole-archive ${old_libs} \

-Wl,--no-whole-archive ${dependency_libs}

我們的程序庫的名稱是${module},動態(tài)鏈接庫的前綴為cyg,輸入庫的前綴為lib。Cygwin的動態(tài)鏈接庫使用cyg作為前綴,以作為本地Windows的MinGW動態(tài)鏈接庫的區(qū)別。${old_libs}是我們?nèi)康哪繕?biāo)文件,被捆綁成靜態(tài)庫或者一個目標(biāo)文件;${dependency_libs}是需要鏈接的靜態(tài)庫,如“-lpng -lz -L/usr/local/special -lmyspeciallib”。

鏈接動態(tài)鏈接庫

假設(shè)您已有一個動態(tài)鏈接庫,并需要建立一個與Cygwin兼容的輸入庫,如果您有源代碼的話,可以參考本文的構(gòu)建動態(tài)鏈接庫部分。如果您沒有源代碼或者沒有可用的輸入庫,那么您可以在bash中創(chuàng)建一個.def 文件,命令如下所示:

echo EXPORTS > foo.def

nm foo.dll | grep ' T _' | sed 's/.* T _//' >> foo.def

只有動態(tài)鏈接庫沒有去除有關(guān)符號信息的情況下上述命令才能正常工作,否則,就會出現(xiàn)“No symbols in foo.dll”錯誤信息。一旦得到了.def文件,就可以從中創(chuàng)建一個輸入庫,命令如下所示:

dlltool --def foo.def --dllname foo.dll --output-lib foo.a

#p#

五、定義Windows資源

Windres能夠讀取Windows資源文件(*.rc),并把它轉(zhuǎn)換成res格式文件或者coff格式文件。輸入文件的語法和語義的同其他任何資源編譯器沒有任何區(qū)別,所以詳情可參閱任何有關(guān)描述Windows資源格式的文獻(xiàn)。此外,windres程序本身在Binutils手冊中也有詳盡的說明。下面是一個使用windres的例子:

myapp.exe : myapp.o myapp.res
	gcc -mwindows myapp.o myapp.res -o $@

myapp.res : myapp.rc resource.h
	windres $< -O coff -o $@

六、結(jié)束語

Cygwin是許多自由軟件的集合,用于各種版本的Microsoft Windows上運行UNIX類系統(tǒng)。Cygwin的主要目的是通過重新編譯,將POSIX系統(tǒng)上的軟件移植到Windows上。Cygwin包括了一套庫,該庫在Win32系統(tǒng)下實現(xiàn)了POSIX系統(tǒng)調(diào)用的API;還有一套GNU開發(fā)工具集(比如GCC、GDB),這樣可以進(jìn)行簡單的軟件開發(fā);還有一些UNIX系統(tǒng)下的常見程序。而本文則為讀者介紹了如何在Cygwin下進(jìn)行程序開發(fā)。我們首先介紹使用GCC開發(fā)控制臺模式的應(yīng)用程序和GUI模式的應(yīng)用程序,然后闡述在Cygwin下如何調(diào)試程序,隨后詳細(xì)講解在Cygwin下動態(tài)鏈接庫的構(gòu)建和使用,最后介紹資源文件的有關(guān)知識。

【編輯推薦】

  1. Linux編程起步 GCC基本用法
  2. 詳解GCC的下載和安裝
  3. 從VC++到GCC移植:談兩者語法差異
責(zé)任編輯:楊鵬飛 來源: 51CTO
相關(guān)推薦

2020-03-07 18:51:11

EclipseFedoraPHP

2022-02-09 15:29:35

Java組件編程語言

2012-11-23 14:33:06

IBMdW

2015-07-23 14:09:15

CygwinWindowsLinux

2023-11-30 15:56:54

大型語言模型人工智能

2010-05-04 08:52:13

Unix系統(tǒng)

2010-02-24 15:19:38

ibmdwLinux

2021-02-16 23:17:47

Windows 10Windows微軟

2010-12-09 09:12:28

2009-04-14 18:50:55

Nehalem惠普intel

2020-02-18 09:45:44

云計算云平臺IT

2010-04-30 18:38:45

Unix系統(tǒng)

2010-11-03 15:27:39

OpenLDAPWindowsUnix系統(tǒng)

2023-06-20 08:00:00

2009-07-16 14:22:02

Windows Emb

2025-04-23 15:49:37

2010-04-29 17:51:40

Unix工具

2011-07-19 14:11:07

Windows iPhone SDK

2010-07-02 12:58:39

Meego開發(fā)

2023-02-09 15:32:55

配置雙網(wǎng)卡雙網(wǎng)卡設(shè)置
點贊
收藏

51CTO技術(shù)棧公眾號