Tại sao lại sử dụng được DLL?
Chào mọi người,
Em đang tìm hiểu về tạo một COM ATL DLL bằng Visual C++. Em có một thắc mắc nhưng chưa tìm được giải đáp, mong mọi người giúp đỡ.
Ở project ATL (P1), em đã tạo được DLL. Trong Project MFC (P2) em muốn dùng DLL đó thì cần include 2 file .h và .c theo đường dẫn tới thư mục chứa 2 file này (.h và .c của P1) trong P1
hoặc
copy 2 file này vào thư mục chạy của P2 thì build và làm như vậy thì chạy được (P2 sử dụng được DLL của P1).
Nhưng em thử copy file .h và .c vào thư mục của P2 xong, em chuyển thư mục chứa P1 đi chỗ khác đi thì P2 sẽ không gọi được DLL của P1.
Vậy mọi người cho em hỏi việc gọi một DLL thì liên quan tới những gì? Tại sao sau khi copy P1 tới một nơi khác thì phải build lại thì khi include file .h và .c ở P2 mới sử dụng được DLL?
Khi compile một file DLL ta cần source code của file DLL đó. Build DLL cũng giống như build EXE, ta cũng cần header và source code, tức file .h và file .c. Tuy nhiên, file DLL không tự nó chạy được, mà nó sẽ là thư viện để cho các chương trình khác đọc.
Một khi compile file DLL thì ta sẽ có được bên trong file DLL là mã máy có thể thực hiện được các tính năng mà ta đã thiết kế cho nó trong file .c. Lúc này, ta không còn cần file .c để sử dụng file DLL nữa, đây là điều mà @bigboybang hiểu nhầm. Ở đây, ta chỉ cần file .h là có thể sử dụng được DLL.
Compile một DLL
Tại sao lại cần file .h mà không cần file .c? Ta có thể hiểu như sau, ta có file .c chứa source code, sau khi compile thì toàn bộ source code sẽ chuyển thành mã máy sẵn sàng thực thi nếu ta load các mã này vào RAM và fetch cho CPU chạy từng instruction.
Cấu trúc của DLL
Vậy làm sao để ta biết đoạn mã nào thực thi? Khi compile xong thì DLL sẽ có một cái “bản đồ” hướng dẫn chi tiết hàm nào, ở vị trí nào trong file DLL này. Ví dụ
Ta có code như sau:
Thì “bản đồ” của file DLL này như sau
Đoạn ví dụ trên được lấy từ wiki của lệnh
nm
trong Linux.Liên kết với DLL
Để sử dụng được DLL thì ta cần phải thông báo cho compiler biết là ta muốn dùng DLL này. Để giúp cho compiler biết cách sử dụng DLL này ta cần 2 thứ.
Compiler sẽ tự biết cách tìm tên hàm.
Quay trở lại câu hỏi của @bigboybang
Như thế này có nghĩa là file DLL nằm trong thư mục P1. Việc copy file .h và file .c vào P2 không thực hiện việc build lại DLL.
Tương tự, việc copy này không build lại DLL. Bản chất P2 vẫn dùng DLL ở P1.
Chỉ cần include file .h là được. Đồng thời P2 cần phải biết đường đẫn của DLL nằm trong P1 là nằm chỗ nào.
Ở đây chắc là @bigboybang sử dụng Visual Studio, nó che dấu bớt rất nhiều thao tác. Giúp cho việc lập trình dễ hơn. Nhưng đồng thời cũng che giấu luôn việc compile DLL diễn ra như thế nào, việc include diễn ra như thế nào.
Ở trường hợp của em, khi tạo một COM ATL DLL thì trong file .c có
IID (Interface ID)
vàCLSID( Class ID)
. Thì khi dùng dll ở P2 thì cần include .c để gọi đến dll. Có thể bỏ include file .c này nếu khi báo luôn IID và CLSID ở P2. Ví dụ:P2:
Nguồn: http://www.codeproject.com/Articles/96/Beginner-s-Tutorial-COM-ATL-Simple-Project Step 6.
Nhân tiện có
IID
vàCLSID
thuộcGUID
, thì cóData4
là{0xA8,0xA8,0x00,0x10,0x5A,0xA9,0x43,0xDF}
. Em đã cố tìm hiểu nhưng không biết dãy số trên từ đâu ra.Liên kết với DLL
Sau khi em build ra được DLL ở P1. Em copy file .h và file .dll và thư mục ở P2. Thì khi xóa P1 đi, build P2 thì không sử dụng được DLL của P1.
–> Vậy có nghĩa là DLL sau khi build ra được, vẫn cần phải nằm đúng vị trí ở P1 thì P2 mới có thể sử dụng được ạ? Giả sử, để sử dụng được DLL ở 1 máy khác thì vẫn cần đưa cả P1 sang máy đó và build thì mới dùng được DLL? (Em thắc mắc điều này là bởi trước em thấy chỉ cần add reference DLL (chỉ mình file .dll không có cả project tạo ra nó) ở 1 máy khác là đã có thể sử dụng được các hàm trong DLL đó).
Đúng ạ, em dùng Visual Studio 2012. .
?! Khi em copy file .h vào P2 rồi, thì complier sẽ tìm file .dll như thế nào? Liệu có phải qua Registry? Em mới lần đầu đi tìm hiểu sâu 1 vấn đề, nên có gì không phải mong anh bỏ qua và hướng dẫn ạ.