2010-10-27 37 views
8

Tôi có vài nghi ngờ về cách cửa sổ quản lý bộ nhớ của .dll.Quản lý bộ nhớ dll

  • khi .dll được tải vào máy chủ quá trình, bộ nhớ được quản lý như thế nào?

  • Dll có quyền truy cập vào toàn bộ bộ nhớ có sẵn cho quy trình lưu trữ hoặc chỉ một phần không? nghĩa là có giới hạn khi bộ nhớ là được phân bổ bởi một hàm bên trong .dll không?

  • Các lớp STL như chuỗi, vectơ (động tăng dung lượng lưu trữ), v.v. được sử dụng bởi dll, có hoạt động không có vấn đề ở đây không?

+0

Câu hỏi liên quan: http://stackoverflow.com/questions/2266218/ –

+0

Một câu hỏi liên quan khác: http://stackoverflow.com/questions/1634773/ –

+0

Câu trả lời được chấp nhận cho câu hỏi này có những gì bạn cần tôi nghĩ: http : //stackoverflow.com/questions/2154939/ –

Trả lời

4

"Quản lý bộ nhớ" là trách nhiệm phân tách, thông thường. Hệ điều hành không gian địa chỉ tay trong khối lớn để chạy, sau đó đưa nó ra trong các bit nhỏ hơn cho chương trình. Không gian địa chỉ này có thể có hoặc không có RAM được cấp phát. (Nếu không, sẽ có không gian hoán đổi để sao lưu)

Về cơ bản, khi một DLL được tải, Windows sẽ phân bổ không gian địa chỉ cho mã và phân đoạn dữ liệu và gọi DllMain(). Trình biên dịch C++ sẽ được sắp xếp để gọi các ctors toàn cầu từ DllMain(). Nếu đó là DLL được viết bằng C++, nó sẽ có khả năng phụ thuộc vào một DLL thời gian chạy C++, do đó sẽ phụ thuộc vào Kernel32.DLL và User32.DLL. Windows hiểu các phụ thuộc như vậy và sẽ sắp xếp cho chúng được tải theo đúng thứ tự.

Chỉ có một không gian địa chỉ để chứng minh, do đó, một DLL sẽ có quyền truy cập vào tất cả bộ nhớ của quá trình. Nếu một DLL được nạp trong hai quy trình, sẽ có hai bản sao hợp lý của mã và dữ liệu. (bản sao của mã và dữ liệu chỉ đọc có thể chia sẻ cùng một RAM vật lý).

Nếu DLL cấp phát bộ nhớ bằng cách sử dụng chức năng OS, Windows sẽ cấp phát bộ nhớ cho quá trình mà từ đó DLL đã thực hiện phân bổ đó. Quá trình này phải trả lại bộ nhớ, nhưng bất kỳ mã nào trong quá trình có thể làm như vậy. Nếu DLL của bạn cấp phát bộ nhớ bằng cách sử dụng các hàm C++, nó sẽ làm như vậy bằng cách gọi operator new trong thời gian chạy DLL C++. Bộ nhớ đó phải được trả lại bằng cách gọi operator delete trong cùng một thời gian chạy DLL C++. Một lần nữa, nó không quan trọng ai làm điều đó.

Các lớp STL như vector<> có thể được nhân nhanh, nhưng không quan trọng miễn là bạn đang sử dụng cùng một trình biên dịch. Tất cả các instantiations sẽ được bằng nhau đáng kể, và tất cả sẽ trả về bộ nhớ của vectơ cho cùng một hàm deallocation.

Có 2 giả thuyết chính trong lời giải thích này:

  1. Các EXE và DLL của nó đều được biên soạn với cùng biên dịch
  2. Các EXE và DLL của nó tất cả các liên kết chống lại C++ runtime DLL (tức là không tĩnh được liên kết)

Kết nối tĩnh với thời gian chạy C++ rất hữu ích nếu bạn muốn gửi một EXE độc lập. Nhưng nếu bạn đã được vận chuyển DLL, bạn nên giữ thời gian chạy C++ trong DLL riêng của nó quá.

+0

* Các lớp STL như vector <> có thể được nhân ngay lập tức, nhưng nó không quan trọng miễn là bạn đang sử dụng cùng một trình biên dịch. * - Một nên thêm rằng nó không chỉ là trình biên dịch giống nhau, mà còn cùng cờ nếu có bất kỳ cờ nào: '_SECURE_SCL' v.v. –

3

Liệu .dll được tiếp cận với toàn bộ bộ nhớ sẵn sàng cho quá trình chủ hoặc chỉ một phần của nó? nghĩa là có giới hạn khi bộ nhớ được phân bổ bởi một hàm bên trong .dll?

Sau một DLL đã được nạp vào quá trình lưu trữ, không có sự khác biệt nào về đang "sống" trong DLL vs mã "sống" trong module thực thi gốc. Đối với quá trình được thực hiện tất cả các phạm vi bộ nhớ là như nhau, cho dù họ đến từ một DLL hoặc từ thực thi ban đầu.

Không có sự khác biệt về mã của DLL có thể làm gì so với mã được biên dịch trong mô-đun exec ban đầu có thể làm.

Điều đó nói rằng, có khác biệt khi sử dụng các đống - đây được giải thích trong các câu hỏi Space_C0wb0y cung cấp các liên kết cho trong comments

Will lớp STL như chuỗi, vector (tăng động lưu trữ) vv được sử dụng bởi dll, công việc không có vấn đề ở đây?

Họ sẽ tạo các vấn đề (có thể giải quyết, nhưng vẫn) nếu bạn sử dụng chúng trong giao diện DLL của bạn. Các sẽ không (hoặc chỉ trong những trường hợp rất hiếm) tạo ra các vấn đề nếu bạn không sử dụng chúng trên cấp độ giao diện DLL. Tôi chắc chắn có một vài câu hỏi cụ thể + câu trả lời xung quanh cho việc này.

Về cơ bản, nếu bạn sử dụng chúng ở cấp độ giao diện, tệp DLL và EXE phải được biên dịch với "chính xác" cùng một cờ, nghĩa là các loại cần phải tương thích nhị phân. I E. nếu các cờ comiler (tối ưu hóa, vv) trong DLL của bạn khác với trong EXE sao cho một std::string được bố trí khác nhau trong bộ nhớ trong EXE và DLL, sau đó truyền một đối tượng chuỗi giữa hai kết quả sẽ dẫn đến tai nạn hoặc lỗi thầm lặng (hoặc quỷ bay ra khỏi mũi của bạn).

Nếu bạn chỉ sử dụng các loại STL bên trong các hàm hoặc giữa các hàm bên trong DLL của bạn, thì tính tương thích của chúng với EXE không quan trọng.

+0

"Họ sẽ tạo ra các vấn đề (những người có thể giải quyết, nhưng vẫn còn) nếu bạn sử dụng chúng trong giao diện của DLL của bạn" - bạn có thể giải thích thêm hoặc đưa ra một ví dụ? – SysAdmin

Các vấn đề liên quan