VicoTas
Câu hỏi
avatar topdaica000
25/05/2013 20:38

Xin hỏi có thể tìm hiểu thuật toán giải hệ phương trình bậc nhất n ẩn số ở đâu?

Xin hỏi có thể tìm hiểu thuật toán giải hệ phương trình bậc nhất n ẩn số ở đâu
Bạn có thể tìm hiểu giải thuật giải hệ phương trình bậc nhất n ẩn số trong các sách giáo trình môn đại số của các trường đại học kỹ thuật. Bạn cũng có thể tìm source code (bằng Pascal, C++...) miêu tả giải thuật giải hệ phương trình n ẩn số trên Internet.

Tôi lập trình bằng Delphi 6, có sử dụng các hàm trong thư viện liên kết động (*.dll). Tôi muốn hỏi về 2 phương pháp gọi hàm động và tĩnh trong thư viện *.dll.
1. Nếu dùng phương pháp tĩnh thì phải khai báo tất cả các hàm sau đó mới dùng được nhưng rất tốn bộ nhớ.
2. Nếu dùng phương pháp động thì dùng hàm nào? nếu mở thư viện *.dll và sử dụng các hàm sau đó kết thúc chương trình mới đóng lại thì có tốn bộ nhớ như phương pháp tĩnh không?
3. Liệu có thể kết hợp cả 2 phương pháp cùng 1 lúc được không?
4. Xin hướng dẫn lập trình điều khiển thiết bị trong WinXP bằng thư viện *.dll.

Danh sách câu trả lời (1)
avatar kjss292003 25/05/2013 20:38
Có 2 phương pháp liên kết code của chương trình ứng dụng với code của các hàm thư viện mà nó dùng: đó là phương pháp liên kết tĩnh và phương pháp liên kết động (hay còn gọi là liên kết muộn tại thời điểm chạy).
1. Trong phương pháp liên kết tĩnh, tại thời điểm dịch và liên kết chương trình, code của các hàm thư viện sẽ được trích ra từ file thư viện và được chèn trực tiếp vào file chương trình (y như do người dùng viết chúng vậy). Sau đó các lệnh gọi hàm thư viện trong chương trình ứng dụng sẽ được hiệu chỉnh lại để thể hiện sự gọi trực tiếp các hàm thư viện này (lúc này nằm cục bộ trong file chương trình ứng dụng). Ưu điểm của phương pháp này là tính đơn giản, dễ hiểu, nhưng phương pháp này có khá nhiều khuyết điểm làm nó không được dùng trong các môi trường hiện đại:
• Làm dung lượng chương trình lớn lên 1 cách không cần thiết vì có thể có nhiều hàm thư viện được nhân bản và được để vào file chương trình nhưng trong nhiều lần chạy chương trình, các hàm thư viện không được gọi lần nào (do luồng thi hành chương trình không đi qua đoạn code chứa lời gọi hàm thư viện).
• Lãng phí tài nguyên bộ nhớ ngoài (đĩa) và bộ nhớ trong (RAM) vì đoạn code của hàm thư viện đã bị nhân bản từ file thư viện và được đặt trực tiếp trong n file phần mềm có gọi hàm đó, nếu số lượng n file này là lớn thì sự lãng phí về dung lượng đĩa (để chứa n file chương trình) và dung lượng RAM (để chạy các chương trình này đồng thời) càng lớn.
• Hành vi của chương trình ứng dụng không thay đổi động khi các hàm thư viện mà nó gọi đã được nâng cấp. Thật vậy, khi file thư viện đã được nâng cấp ta phải dịch và liên kết chương trình với file thư viện mới, nếu không, ứng dụng vẫn gọi version cũ của hàm thư viện chứ không phải version hiện hành của file thư viện.
2. Trong phương pháp liên kết động, lệnh gọi hàm thư viện trong file chương trình chưa được liên kết với hàm tại thời điểm dịch. Khi chương trình chạy, mỗi khi cần phải thực thi 1 lệnh gọi hàm thư viện, hệ thống mới dừng lại, xác định file thư viện nào và nếu nó chưa được nạp vào bộ nhớ trước đó thì hệ thống sẽ nạp vào (nhưng thường được để trong không gian bộ nhớ dùng chung để có thể "share" cho nhiều chương trình gọi nó). Sau khi đã nạp file thư viện vào bộ nhớ, hệ thống mới liên kết lời gọi hàm thư viện với hàm đó rồi cho chương trình chạy tiếp. Với cách làm này, sự liên kết giữa lời gọi và hàm thư viện chỉ xảy ra 1 lần, lần đầu tiên lệnh gọi hàm được chạy. Phương pháp liên kết động có rất nhiều ưu điểm nên được sử dụng chủ yếu trong các môi trường hiện nay như Windows, Linux... Trên Windows, việc liên kết lời gọi hàm với hàm thư viện có thể được thực hiện tường minh bởi người lập trình tại vị trí xác định trong chương trình với đoạn code "template" như sau:
//định nghĩa biến pointer đến hàm thư viện
typedef int FAR (*ATMBEGINFCHANGE)(void);
ATMBEGINFCHANGE ATMBeginFontChange, ATMEndFontChange;
//load file thư viện chứa hàm cần gọi vào bộ nhớ dùng chung
hATMLIB = LoadLibrary((LPCSTR)"atmlib.dll") ;
if (hATMLIB == NULL)
MessageBox(NULL,"Load atmlib.dll Error","Error",MB_OK );
//xác định địa chỉ đầu của hàm thư viện cần gọi
ATMBeginFontChange = (ATMBEGINFCHANGE)GetProcAddress(hATMLIB, "ATMBeginFontChange");
if (ATMBeginFontChange == NULL)
MessageBox(NULL,"Khong the tim ham ATMBeginFontChange","Error",MB_OK);
...
//khi cần, gọi hàm thông qua biến pointer
ATMBeginFontChange();
Đoạn code thực hiện liên kết động 1 cách tường minh như trên khá rườm rà, một mặt gây khó khăn cho người viết, mặt khác gây khó khăn cho người đọc lại đoạn code để hiểu nó. Chính vì vậy, khi dịch file thư viện, các tool biên dịch và liên kết trên Windows như Borland C++, VC++, ... luôn tạo ra 2 file thư viện khác nhau:
• file *.dll chứa các hàm thư viện đã được dịch.
• file *.lib chứa các đoạn code thực hiện liên kết động cho từng hàm thư viện (giống như đoạn code trên).
Khi dịch và liên kết chương trình ứng dụng, chương trình liên kết sẽ dịch lời gọi hàm thư viện thành lời gọi hàm tương ứng trong file *.lib và hàm này thực hiện liên kết động với hàm thư viện. Ở đây bạn cần lưu ý là chương trình dịch dùng phương pháp liên kết tĩnh với đoạn code trong file *.lib, chỉ có đoạn code này mới thực hiện liên kết động với hàm trong file *.dll.
Một lưu ý khác là để 1 file source C++ gọi được 1 hàm nằm trong file khác (thường là thư viện), ta phải khai báo trước đặc tả sử dụng hàm cần gọi rồi sau đó mới gọi nó. Lệnh khai báo đặc tả sử dụng 1 hàm sẽ miêu tả tên hàm, danh sách từng tham số, mỗi tham số thuộc kiểu dữ liệu nào, và đặc tả chức năng của hàm đó. Thường các lệnh khai báo đặc tả hàm được để trong file *.h, file source C++ sẽ dùng lệnh "#include" để chèn nội dung file *.h vào file source. Khi dịch, các lệnh khai báo chỉ cung cấp thông tin cho chương trình dịch chứ không được dịch ra mã máy nên không hề tốn bộ nhớ cho chúng.
3. Về nguyên tắc, bạn có thể dùng kết hợp 2 phương pháp liên kết tĩnh và động trong cùng 1 phần mềm. Tuy nhiên thường người ta sẽ chọn dùng 1 phương pháp để đảm bảo tính nhất quán và dễ theo dõi.
4. Chúng tôi đã trả lời vấn đề này trên các số báo trước, xin nhắc lại WinXP có cơ chế bảo vệ tài nguyên rất chặt chẽ, các lệnh trong file ứng dụng không được phép truy xuất trực tiếp các tài nguyên của máy (thí dụ truy xuất các cổng I/O của các card chức năng). Nếu muốn, bạn phải xây dựng 1 device driver theo định dạng của WinXP, device driver này sẽ chứa các đoạn code truy xuất trực tiếp tài nguyên và nó được chạy ở cấp ưu tiên cao nhất như các đoạn code của HĐH. Chi tiết về việc xây dựng device driver được trình bày trong CD DDK (Device Development Kit).
Trong VB.NET tôi có khai báo hàm như sau:
Private Sub ShowImage(ByVal position As Integer, ByVal index As Integer)
Dim a_label As New Label
a_label.Name = "lblCell" & position.ToString
Nếu index = 0 thì xoá hình khỏi a_label
If index = 0 Then
a_label.Image = Nothing
a_label.Refresh()
Else
Select Case position
Case 0 Or 6
a_label.Image = Image.FromFile("D:\My Documents\My Projects\Visual Studio Projects\O_Quan\Images\quan1" & index.ToString & ".jpg")
a_label.Refresh()
Case 1 To 5
a_label.Image = Image.FromFile("D:\My Documents\Mư Projects\Visual Studio Projects\O_Quan\Images\" & index.ToString & "r.jpg")
a_label.Refresh()
Case 7 To 11
a_label.Image = Image.FromFile("D:\My Documents\Mư Projects\Visual Studio Projects\O_Quan\Images\" & index.ToString & "b.jpg")
a_label.Refresh()
End Select
End If
a_label.Refresh()
a_label.Update()
End Sub
Các Label lblCellposition đã có sẵn trên form. Nhưng khi chạy chương trình thì hình ảnh trên lblCellposition không có thay đổi gì cả. Xin hỏi có phải khai báo hàm trên sai ở chỗ gán "a_label.Name" không? Xin chỉ cách khắc phục.
Đúng, hơn nữa, bạn còn mắc phải 1 số lỗi khác nữa:
• lệnh Case 0 Or 6 tương đương với lệnh Case 0 vì kết quả tính biểu thức "0 Or 6" sẽ là 0. Do đó nếu muốn miêu tả 2 trường hợp 0 và 6, bạn nên dùng 2 lệnh "Case 0" và "Case 6" riêng biệt.
• Các đoạn code mà bạn thực hiện để thiết lập ảnh bitmap cho các label thực sự chỉ tác động trên đối tượng a_label mà đối tượng này được tạo động bằng chương trình và chưa liên kết với form giao diện. Lưu ý để truy xuất 1 đối tượng giao diện nào đó, bạn phải dùng biến tham khảo đến nó (thí dụ a_label). Bạn có 12 label với tên lần lượt là lblCell0 đến lblCell12, muốn truy xuất label nào, bạn phải dùng đúng tên biến tương ứng, biến này chính là thuộc tính "Name" mà bạn đã thiết lập tại thời điểm thiết kế trực quan.
Tóm lại để có thể thay đổi được ảnh bitmap của các label, bạn có thể hiệu chỉnh đoạn code của mình thành:
Private Sub ShowImage(ByVal position As Integer, ByVal index As Integer)
Dim filename As String
Xác định file chứa ảnh cần dùng
Select Case position
Case 0
filename = "D:\My Documents\My Projects\Visual Studio Projects\O_Quan\Images\quan1" & index.ToString & ".jpg"
Case 6
filename = "D:\My Documents\My Projects\Visual Studio Projects\O_Quan\Images\quan1" & index.ToString & ".jpg"
Case 1 To 5
filename = "D:\My Documents\Mư Projects\Visual Studio Projects\O_Quan\Images\" & index.ToString & "r.jpg"
Case 7 To 11
filename = "D:\My Documents\Mư Projects\Visual Studio Projects\O_Quan\Images\" & index.ToString & "b.jpg"
End Select
Select Case index
Nếu index = 0 thì xóa ảnh khỏi label
Case 0
Select Case position
Case 0
lblCell0.Image = Nothing
Case 1
lblCell1.Image = Nothing
Case 2
lblCell2.Image = Nothing
...
Case 11
lblCell11.Image = Nothing
End Select
Nếu index = 1 thì thiết lập ảnh cho label tương ứng
Case 1
Select Case position
Case 0
lblCell0.Image = Image.FromFile(filename)
Case 1
lblCell1.Image = Image.FromFile(filename)
Case 2
lblCell2.Image = Image.FromFile(filename)
...
Case 11
lblCell11.Image = Image.FromFile(filename)
End Select
End Select
End Sub
Cho hỏi trong VB.Net, làm sao để "Extract" một icon từ những file *.exe?
Bạn có thể gọi hàm API của Windows tên là ExtractIcon() để đọc icon từ 1 file khả thi nào đó (*.exe, *.dll, *.ocx...). Lưu ý 1 file khả thi có thể chứa nhiều icon khác nhau, mỗi icon được nhận dạng thông qua chỉ số từ 0 đến n. Đoạn code VB .Net sau sẽ đọc icon đầu tiên trong file *.exe (thường đó là icon miêu tả chương trình ứng dụng) rồi hiển thị nó lên ở góc trên trái của form hiện hành :
khai báo hàm API cần dùng
Private Declare Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As Integer, ByVal lpszExeFileName As String, ByVal nIconIndex As Integer) As System.IntPtr
khai báo biến quản lý icon
Dim hIcon As System.IntPtr
Dim ic As Icon
đọc icon đầu tiên (chỉ số 0) của file *.exe vào
hIcon = ExtractIcon(VB6.GetHInstance.ToInt32, "c:\windows\prog.exe", 0)
tạo đối tượng Icon tương ứng
ic = Icon.FromHandle(hIcon)
hiển thị icon lên góc trên trái của form hiện hành
Me.CreateGraphics.DrawIcon(ic, 0, 0)
Chúc bạn thành công!
Trả lời câu hỏi
Tải lại mã
Câu hỏi lĩnh vực Lập trình
nophoto Có cách nào giấu 1 ứng dụng viết bằng Delphi trong Task Manager của Win9x và WinXP không?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Trong VB.NET, làm cách nào để biết được sự kiện bấm phím khi đang làm việc ở cửa sổ khác?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Xin hướng dẫn cách tạo một chương trình liệt kê ổ đĩa và thư mục vào trong TreeView bằng Win32 API, giống như chức năng của Norton Commander?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Trong các chương trình như VB, Pascal... làm sao để khi chạy chương trình có thể nhập vào một biểu thức để gán cho một hàm, ví dụ như: x*x+3*cos(x)?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Tôi làm chương trình từ điển đọc từ vựng tiếng Anh bằng VB, nhưng ko biết cách truy xuất tập tin âm thanh (.wav) trong CSDL (Access) để phát ra loa?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Làm thế nào để một ứng dụng biết được 1 ứng dụng khác đã cài trên máy? Có cách nào giấu ứng dụng đã cài?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Xin hướng dẫn viết chương trình nhận dạng tiếng nói và chuyển thành văn bản?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Xin hỏi có cách nào chạy trực tiếp tập tin *.pas mà không cần chương trình?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Xin hướng dẫn cách tạo chương trình trò chơi bằng Java?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Xin hướng dẫn cách lập trình VC++ quản lý thread trong Windows?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Một chương trình đang chạy, có cách nào để ngắt giữa chừng và chèn vào lệnh thực thi một chương trình khác?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Làm sao để người khác không copy được nội dung trang web của mình?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Hướng dẫn cho mình cách xây dựng menubar trong C++. ?

Đăng lúc: 20:38 - 25/05/2013 trong Lập trình

nophoto Nên viết trình điều khiển scanner và quản lý dữ liệu của scanner bằng ngôn ngữ gì là thích hợp nhất? Có thể dùng Visual C++ 6.0 không?

Đăng lúc: 20:37 - 25/05/2013 trong Lập trình

nophoto Tôi muốn viết các games nhỏ như cờ caro hoặc cờ tướng dùng VC++ 6.0?

Đăng lúc: 20:37 - 25/05/2013 trong Lập trình

nophoto Tôi cần vẽ ra form trong C#, nhưng khi di chuyển form, các khối vẽ bị mất đi và phải vẽ lại. Xin hướng dẫn cách tạo form có tính năng Redraw giống VB?

Đăng lúc: 20:37 - 25/05/2013 trong Lập trình

Hương Xin hướng dẫn cách mã hóa 1 trường (cột) trong 1 bảng FoxPro để không cho người ngoài xem được nội dung?

Đăng lúc: 20:37 - 25/05/2013 trong Lập trình

nophoto Cho hỏi 3 ngôn ngữ lập trình C, C++ và C# khác nhau chỗ nào?

Đăng lúc: 20:37 - 25/05/2013 trong Lập trình

nophoto Xin hướng dẫn lập trình VB6 chặn các thông tin gửi từ máy tính lên mạng. Nếu chặn được thì có thể thay đổi thông tin đó không?

Đăng lúc: 20:37 - 25/05/2013 trong Lập trình

nophoto Có 1 số OCX hay DLL hỗ trợ đọc barcode, tôi có thể lập trình thử nghiệm mà không cần có máy đọc barcode được không?

Đăng lúc: 20:37 - 25/05/2013 trong Lập trình

Rao vặt Siêu Vip