Bộ công cụ phát triển ứng dụng GNU * GNU Compiler Collection GCC + Thư việncác hàm tiện ích: libc, libstdc++, … + Các trình biên dịch gcc, g++, gcj, gas, … + Trình khử lỗigdb +Trình tiện
Trang 1ĐỀ ÁN GIỮA HỌC KỲ
SỰ KHÁC NHAU GIỮA C++ TRÊN WINDOWS VÀ LINUX
I - Giới thiệu sơ lược:
Linux là hệ điều hành nguồn mở Tức là Linux giống như Windows ở chỗ nó là cái nền quản lý mọi thứ khi bạn sử dụng máy tính Nó quản lý các ứng dụng đang chạy, quản lý những thông tin về người dùng, quản lý dữ liệu trên đĩa cứng…
Ngoài ra nó còn cung cấp cho các chương trình phần mềm những tài nguyên để chúng có thể chạy được Chính vì thế một phần mềm được viết ra để chạy trên hệ điều hành này sẽ khôngthể (thông thường là thế) chạy trên hệ điều hành khác Muốn chạy được thì lập trình viên phải viết một phiên bản riêng dành cho hệ điều hành cần thiết Đó chính là lý do vì sao người dùng Linux gặp trở ngại trong làm việc, vì hầu hết những phần mềm cao cấp đắt tiền như Office, CorelDraw, Adobe các loại… không có phiên bản chạy trên Linux Tuy nhiên, may mắn là thế giới phần mềm nguồn mở lại luôn có sẵn những phần mềm cho Linux, mặc dù chúng có thể chưa so sánh được với những phần mềm nguồn đóng đắt tiền kia, nhưng hoàn toàn phù hợp chonhu cầu hàng ngày
Trình biên dịch C trên Linux chỉ là một phần GCC (GNU Compiler Collection) GCC có thể dùng được với: C, C++, Objective C, Fortran,…
Biên dịch C là "gcc"
Biên dịch C++ là "g++"
Bộ công cụ phát triển ứng dụng GNU
* GNU Compiler Collection (GCC)
+ Thư việncác hàm tiện ích: libc, libstdc++, …
+ Các trình biên dịch gcc, g++, gcj, gas, …
+ Trình khử lỗigdb
+Trình tiện ích khác trong binutils như nm, strip, ar, objdump, ranlib (dùng lệnh info
binutils để xem thêm)
Tiệních: gmake…
Sơ lược về hoạt động của g++ trong linux
Trang 2Trình soạn thảo code và cách thức biên dịch C++ trong linux
Biên
Biên dịch dịch chương chương trình nh C/C++ C/C++
*Biên dịch (không link) file chương trình nguồn C++
Vd: g++ -c myprog.cpp
+ Kết quả là file object tên là myprog.o
*Biên dịch (không link) main.c có sử dụng các file *.h trong thư mục include/ (dùng tùy chọn -I
*Liên kết (link) nhiều file đối tượng (object files) đã có
Vd: g++ -o myapp main.o reciprocal.o
*Giả sử ứng dụng của bạn gồm nhiều hơn một file source code, e.g main.c và reciprocal.c Để tạo thành chương trình thực thi, bạn có thể biên dịch trực tiếp bằng một lệnh g++ như sau:
Vd: g++ -o myapp main.c reciprocal.c
Cách làm thủ công như trên sẽ bất tiện và không hiệu quả khi ứng dụng gồm quá nhiều file
Trang 3Trong Windows:
Trang 4Trong windows thi sau khi viết xong đoạn code cho chương trình thì ta chỉ cần nhấn những tổ hợp phím:
+F7: Biên dịch chương trình
+Ctrl F5: Để chạy file thực thi
+Shift F5: Để chạy debug
Trong Trường hợp đoạn code bi lỗi thi sau khi nhấn F7 chương trinh sẽ báo lỗi cho ta.Khi đó thì
ta nhấn phím F4 để biết được đoạn code của ta bị lỗi gì và ở đâu
II Cách khai báo thư viện:
Thư viện: cả hai đều có thư viện lệnh chuẩn như: string.h,stdio.h……
Tuy nhiên trong đó thư viện dùng để khai báo hàm nhập và xuất(hàm iostream.h trong windows và iostream trong linux Xem hình minh họa bên dưới) của của windows và linux lại khác nhau.Một cách chính xác là cách khai báo trong linux cũng có thể dùng trong windows được
Trong Linux không sử dụng thư viện lệnh <conio.h> nhưng thay vào đó lại là
lệnh<curses.h>
#include <thu vien lenh>
Vd: #include <iostream.h>
Các câu bắt đầu bằng dấu (#) được dùng cho preprocessor Chúng không phải là những dòng
mã thực hiện nhưng được dùng để báo hiệu cho trình dịch Ở đây câu lệnh #include
<iostream.h> báo cho trình dịch biết cần phải "include" thư viện iostream Đây là một thư viện vào ra cơ bản trong C++ và nó phải được "include" vì nó sẽ được dùng trong chương trình Đây là cách cổ điển để sử dụng thư viện iostream
Void main () hay int main ()
Dòng này tương ứng với phần bắt đầu khai báo hàm main Hàm main là điểm mà tất cả các chương trình C++ bắt đầu thực hiện Nó không phụ thuộc vào vị trí của hàm này (ở đầu, cuối hay ở giữa của mã nguồn) mà nội dung của nó luôn được thực hiện đầu tiên khi chương trình bắt đầu Thêm vào đó, do nguyên nhân nói trên, mọi chương trình C++ đều phải tồn tại một hàm main
Theo sau main là một cặp ngoặc đơn bởi vì nó là một hàm Trong C++, tất cả các hàm mà sau
đó là một cặp ngoặc đơn () thì có nghĩa là nó có thể có hoặc không có tham số (không bắt buộc) Nội dung của hàm main tiếp ngay sau phần khai báo chính thức được bao trong các ngoặc nhọn ( { } ) như trong ví dụ của chúng ta
Trang 5Trong windows:
Trong linux:
Windows:
1 MFC (Microsoft Foundation Class)
Thư viện MFC (Microsoft Foundation Class) là thư viện tập hợp các lớp hướng
đối tượng đóng gói các hàm API của Windows và các kiểu dữ liệu đặc biệt Bên cạnh
sử dụng thư viện MFC trong Visual C++ 6.0, chúng ta có thể sử dụng các hàm C
chuẩn
2 MSDN (Microsoft Developer Network)
Trong MSDN, ngoài các tài liệu giới thiệu chi tiết về việc sử dụng những hàm,lớp…, còn
có các quyển sách, bài báo kỹ thuật, hay các mẫu code có thể được tận dụng trong việc lập trình
Linux:
1 Static libraries:
Tên thường có "lib" và mở rộng ".a"
Trang 6Ví dụ: libmyprog.a
2 Shared libraries:
Tên có "lib" và phần mở rộng ".so"
Ví dụ: libmyprog.so
Trước khi được sử dụng thì thư viện phải được cài đặt Việc cài đặt thư viện gần như rất
dễ dàng và đơn giản với người đã từng sử dụng Linux
Các thư viện có thể nên cài vào máy là: ncurses, SVGALib và ngoài ra có thể sử dụng các
đồ họa cấp cao như GTK/Qt/FLTK thậm chí trực tiếp với X
+ Archives (static library)
Là tập hợp các file object tạo thành một file đơn nhất
Tương tự file LIB trên Windows
Khi bạn chỉ định liên kết ứng dụng của mình với một static library thì linker sẽ tìm trong thư viện đó để trích xuất những file object mà bạn cần Sau đó, linker sẽ tiến hành liên kết các file object đó vào chương trình của bạn
Cách thức tạo thư viện tĩnh (archive file)
Giả sử bạn có hai file mã nguồn chứa hàm là a.c và b.c
return 7; return 3.14159;
Tạo thư viện tĩnh tên là libab.a
1 Biên dịch tạo các file object
$ gcc -c a.c b.c
2 Dùng lệnh ar để tạo thành thư viện tĩnh tên là libab.a
$ ar cr libab.a a.o b.o
3 Có thể dùng lệnh nm để xem lại kết quả
$ nm libab.a
4 Có thể dùng lệnh file để xem file libab.a là loại file gì
$ file libab.a
Tạo ứng dụng đơn giản có sử dụng hàm thư viện trong a.c
Vidu: Tên file là myapp.c
Trang 7/tmp/cc2dMic1.o(.text+0x7): undefined reference to `func1'
collect2: ld returned 1 exit status
Biên dịch có link đến thư viện tĩnh libab.a
$ gcc -o myapp myapp.c -L -lab hoặc gcc -o myapp myapp.c libab.a
$ /myapp
Kết quả dùng hàm func1: 7
Thư viện liên kết động (dynamic, shared library)
Tương tự thư viện dạng DLL của Windows
Thư mục chứa thư viện chuẩn
+/usr/lib, /lib
Tạo thư viện liên kết động libab.so từ a.c và b.c
1 Biên dịch tạo các file object có dùng tùy chọn -fPIC
$ g++ -c -fPIC a.c b.c
2 Tạo thư viện liên kết động tên là libab.so
$ g++ -shared -fPIC -o libab.so a.o b.o
3 Có thể dùng lệnh file để xem file libab.so là loại file gì
$ file libab.so
Note:libab.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), not stripped.
Tạo ứng dụng với file myapp.c như ví dụ trước
Biên dịch link với thư viện tĩnh libab.so
$ g++ myapp.c
Biên dịch có link đến thư viện tĩnh libab.a
G++ -o myapp myapp.c libab.so
/myapp
Thông báo lỗi:./myapp: error while loading shared libraries: libab.so: cannot open shared
object file: No such file or directory -
Tại sao???
Nguyên nhân: do loader tìm trong thư mục thư viện chuẩn như /usr/lib, /lib không có libab.so Cách giải quyết (cũng là cách dùng để triển khai - deploy, một ứng dụng có sử dụng thư viện liên kết động)
1 Nếu có đủ quyền hạn (e.g root) thì copy các file thư viện chia sẻ và thư mục chuẩn
# cp libab.so /lib
./myapp
Trang 8Một số chú ý khi lập trình với thư viện liên kết động.
Kiểm tra xem ứng dụng cuối cùng của mình tạo ra phụ thuộc vào các thư viện liên kết động nàobằng lệnh ldd Nếu bị thiếu thư viện thì phải khắc phục theo 2 cách ở trên
$ mv libab.so libab.so.old
$ gcc -static -o myapp myapp.c -L -lab
$ /myapp
Kết quả dùng hàm func1: 7
Trang 9Đây là không gian tương tác giúp lập trình viên nhanh
nguyên trong project (Tắt/ Mở workspace : Alt + 0
hoặc View/Workspace) Workspace gồm có 3 tab
chính (có thể có các tab phụ add-in): ClassView,
ResourceView, FileView Nội dung các tab này được
thể hiện ở dạng cây có thể mở rộng, thu hẹp thông qua
các nút +, -
Trang 10ClassView cho thấy hình ảnh tổng thể project dưới dạng các lớp Trong classview, lập trình viên có thể biết được cấu tạo của một lớp (có những hàm, biến nào; tầm vực hoạt động của các hàm, các biến – public, protected, private).
ResourceView cho thấy được những tài nguyên có
trong project (dialog, menu, toolbar, bitmap, icon, …)
Thực chất đây là phần hiện thực hoá những gì thể hiện
trong tập tin resource.h và rc
FileView cho thấy những tập tin có trong
tin được thêm vào sau
Đó là vùng dùng để thiết kế giao diện (các dialog, menu, toolbar) hay viết code
cho project
Output
Vùng thể hiện các thông báo lỗi (nếu có), các kết quả thực thi (khi có sử dụng
Macro), nội dung của biến (ở chế độ Debug) …
Trang 11Các control chuẩn
Hộp Control
Trong môi trường lập trình VC++ 6.0 có thể thực hiện việc kéo thả các control chuẩn trong khi thiết kế giao diện Bật/tắt hộp control khi thiết kế thực hiện như sau: nhấn phím chuột phải trên thanh toolbar, một menu như bên tay
phải xuất hiện, chọn (không chọn) chức năng Controls Ngoài ra, cũng có thể vào Tools\
Customize, check vào toolbars ở vị trí Controls
Các control chuẩn
Visual C++ 6.0 cho phép chèn các control chuẩn sau đây vào trong ứng dụng PictureBox, StaticText (Label), Edit box (Textbox), GroupBox, Button, Checkbox, RadioButton, ComboBox, ListBox, Scrollbar, Spin, Progressbar, Slider, TreeControl, Tab Control, Animate, RichEdit, DateTime, Month Calendar, IP Address
Mỗi control có một định danh (ID) riêng ID chính một số nguyên duy nhất
giúp xác định duy nhất một control Tuy nhiên, để dễ nhớ trong quá trình lập trình, lập
trình viên xác định một control bằng một tên duy nhất (tốt nhất thể hiện BẰNG CHỮ
Trang 12chương trình lên hệ thống) Windows sẽ tiếp nhận các sự kiện rồi gửi đến cho các ứng dụng đang chạy.
Ví dụ : nhấn phím, nhấn chuột trái, nhấn chuột phải, vẽ lại màn hình, thay đổi chọn lựa, bắt đầu chương trình, thoát khỏi chương trình…
Các ứng dụng nhận được “thông báo” từ Windows rồi tuỳ theo “nhu cầu” có “tiếp nhận” hay không Nếu “tiếp nhận” sự kiện thì phải “giải quyết” như thế nào Việc giải quyết được đặt trong hàm xử lý sự kiện
Sử dụng ClassWizard để tạo hàm xử lý cho các sự kiện (lên chương trình hay lên một control
cụ thể) (Phím tắt : Ctrl – W Ở chế độ thiết kế dialog có thể nhấn phím chuột phải và chọn mục ClassWizard trên menu.)
Trên hộp thoại MFC ClassWizard, có thể chọn lựa lớp (trong Class name), ID của đối tượng (Object IDs) cần thêm sự kiện vào (Messages)
Sau khi chọn Add Functions, môi trường lập trình sẽ tự động thêm khai báo hàm, cấu trúc hàm vào những vị trí thích hợp trên tập tin CPP và H của lớp Vùng màn hình Context chobiết giá trị của các biến có trong đoạn chương trình đang chạy (kiểm lỗi) Các biến này được đưa vào một cách tự động
Vùng màn hình Watch cho biết giá trị của các biến do lập trình viên mong muốn
Vùng màn hình Call Stack cho biết thứ tự gọi hàm của chương trình
Vùng màn hình Registers cho biết giá trị các thanh ghi
LINUX:
Nếu sử dụng C/C++ chuẩn thì cũng như trên windows, sử dụng ubuntu trước tiên bạn phải cài thêm 2 gói là libstdc++-dev và build essential (vì ubuntu chỉ có các gói cơ bản không hỗ trợ cholập trình) Để cài đặt mở console gõ lệnh:
sudo apt-get install libstdc++-dev sudo apt-get install build-essential.
Sau khi cài 2 gói này bạn có thể bắt đầu Sử dụng editor có sẵn là gedit, soạn thảo chương trình của bạn, lưu với *.c/*.cpp (vd: hello.c)
Các bước biên dịch trong linux
• Công cụ dùng biên dịch các chương trình C/C++
• Quá trình biên dịch thành file thực thi gồm 4 giai đoạn theo thứ tự như sau:
1 Preprocessing (tiền xử lý)
2 Compilation (biên dịch)
3 Assembly (hợpdịch)
4 Linking (liên kết)
• Ba bước 1, 2, 3 chủ yếulàm việc với một file đầuvào
• Bước4 có thể liên kết nhiều object module liên quan để tạo thành file thực thi nhị phân
• Lập trình viên có thể can thiệpvào từng bước ở trên
Mở console(terminal) gõ lệnh chỉ đến thư mục chứa file nguồn, gõ lệnh biên dịch:
Trang 13g++ hello.cpp -o hello
nếu thấy không báo lỗi gì là đã biên dịch thành công, chạy chương trình bạn gõ
./hello
Lưu ý executable file trong linux không có phần mở rộng như trong windows (*.exe)
Cách biên soạn 1 mã nguồn G++ :
Để biên soạn mã nguồn của bạn, trước tiên bạn phải nằm trong thư mục của bạn có mã nguồn file được in Ví dụ, nếu bạn muốn biên tập tin ~ / projects/proj2/proj2.cc, trước tiên bạn cần phải thay đổi để thư mục ~ / projects / proj2 bằng cách sử dụng lệnh cd
Sau khi bạn đang có trong thư mục chính xác, biên soạn các mã nguồn trong các tệp tin proj2.ccbằng cách gõ lệnh sau tại dấu nhắc xterm:
Trang 14Trong đó không có trường hợp tập tin không thi hành được và bạn sẽ được đưa trở về dấu nhắc lệnh
Bây giờ, hãy giả định rằng mã nguồn của bạn đã không có lỗi trong nó Bằng cách sử dụng lệnhtrên, thi hanh một tập tin sẽ được tạo ra trong thư mục hiện thời gọi là a.out Để thực sự chạy các chương trình, chỉ cần gõ tại dấu nhắc lệnh / A.out:
Trang 15sử dụng gdb debugger
-Wall
Để sử dụng các -Wall flag, chỉ cần viết nó giống với g-flag:
g++ -Wall source_file.cc g + +-Wall source_file.cc -Wall flag sẽ hiển thị tất cả các thông điệp cảnh báo về các lỗi trong mã nguồn của bạn Nếu cảnh báo chỉ là những tin nhắn mà bạn nhận được khi bạn biên soạn mã nguồn của bạn, thì tập tin vẫn sẽ được thi hành Chỉ khi có thông báo ERROR thì tập tin mới không được thực hiện Tuy nhiên, nhiều giáo sư trong các trường sẽ trừ điểm nếu mã nguồn của bạn viết có cảnh báo khi biên soạn
-o
-o flag là một trong những công cụ hữu ích This flag will allow you to rename the executable file from something other than a.out Cờ này sẽ cho phép bạn đổi tên các tệp tin thi hành thành những tên khác a.out.Để sử dụng tùy chọn-o, đặt nó sau tập tin mã nguồn, theo sau là tên mà bạn muốn cung cấp cho các lệnh thi hành Ví dụ, để đổi một tập tin tên mã nguồn proj2.cc thànhmột tập tin gọi là proj2.exe, gõ lệnh sau:
g++ proj2.cc -o proj2.exe g + + proj2.cc-o proj2.exe
Làm như thế sẽ tạo ra tập tin thi hanh proj2.exe mà bạn sẽ gõ tại dấu nhắc lệnh để chạy chươngtrình của bạn
Có thể sử dụng nhiều hơn một cờ cùng một lúc khi bạn biên soạn Ví dụ, giả sử bạn nhập vào sau lệnh g++:
g++ -g -Wall proj2.cc -o proj2 Lệnh này sẽ biên soạn tập tin mã nguồn proj2.cc để có thể sửa lỗi với gdb debugger (-g), hiển thị tất cả các thông điệp cảnh báo khi biên soạn (-Wall), và sẽ tạo ra tập tin thi hành gọi là proj2 (-o proj2)
Biên soạn chương trình có nhiều file :
Để làm như vậy, chỉ cần lập danh sách tất cả các mã nguồn cái này nối tiếp cái kia :
Trang 16g++ source_file_1 source_file_2 source_file_3 g + + source_file_1 source_file_2
Các lệnh trên sẽ biên soạn hai tập tin nguồn và tạo ra một lệnh thi hành a.out
NOTE - KHÔNG đưa BẤT KỲ file H nào vào LỆNH g++! Làm như vậy sẽ cho lỗi!
Ngoài ra, giống như bạn làm với chương trình đơn, bạn có thể thêm tuỳ chọn cờ khi bạn biên soạn:
g++ -g -Wall functions.cc proj2.cc -o proj2 g + +-g-Wall functions.cc proj2.cc-o proj2 Lệnh này sẽ biên soạn hai tập tin nguồn functions.cc và proj2.cc đó, để tập tin thi hành có thể
được sử dụng với các gdb debugger (-g), tất cả các biên cảnh báo sẽ được hiển thị (-Wall), và
các tệp tin thi hanh sẽ được gọi là proj2 (-O proj2)
Tất nhiên, g++ có thêm nhiều chức năng hơn những gì được mô tả trong hướng dẫn này Để xem có danh sách đầy đủ của lệnh g++, viết tại dấu nhắc lệnh:
man g++