2010-04-09 68 views
5

C++ Cách lấy tên tệp (và đường dẫn) của mô-đun .so đang chạy trong Unix?C++ Cách lấy tên tệp (và đường dẫn) của mô-đun thực hiện .so trong Unix

Điều gì đó tương tự như GetModuleFileName trên Windows.

+2

Khi bạn có đường dẫn, bạn định làm gì với nó? –

+0

về cơ bản những gì tôi muốn làm là để thả tập tin cấu hình vào cùng một thư mục như tập tin .so của tôi, sau đó tôi cần để có được một đường dẫn đầy đủ để cấu hình tập tin và sau đó để vượt qua tên đầy đủ này để xml config parser. – Steve

+2

Việc sử dụng một [đường dẫn riêng cho các tệp cấu hình] (http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html), vì vậy bạn không cần điều này. –

Trả lời

6

Mặc dù nó không phải là một giao diện tiêu chuẩn POSIX, các dladdr() chức năng có sẵn trên nhiều hệ thống bao gồm Linux, Solaris, Darwin/Mac OS X, FreeBSD, HP-UX, và IRIX. Hàm này lấy một địa chỉ, có thể là một con trỏ trỏ đến một hàm tĩnh trong mô-đun ví dụ (nếu cast thành void *), và điền vào một cấu trúc Dl_info với thông tin bao gồm tên đường dẫn của đối tượng dùng chung chứa địa chỉ đó (trong dli_fname hội viên).

+0

Nếu tôi vẫn có thể bỏ phiếu, tôi sẽ đưa ra +1 để trả lời câu hỏi gốc . –

+0

Bây giờ tôi có thể bỏ phiếu, +1. –

+0

BTW tìm thấy câu trả lời trên SO (đã được hỏi 5 tháng trước): http://stackoverflow.com/questions/1681060/library-path-when-dynamically-loaded – Steve

2

Thật không may, không có cách nào để thực hiện điều đó bằng UNIX hoặc POSIX. Nếu bạn cần sử dụng nó để tìm kiếm một số loại dữ liệu, bạn nên sử dụng biến môi trường $ PATH và tìm kiếm dữ liệu trong một đường dẫn có liên quan đến mỗi mục trong $ PATH. Ví dụ: không lưu trữ các tệp nhị phân trong " installdir/bin" cho một số thư mục cài đặt "installdir" và lưu trữ dữ liệu được liên kết trong " installdir/share/ name_of_program" cho một số thư mục cài đặt và một số chương trình có tên "name_of_program". Nếu đúng như vậy, hãy xem "../share/ name_of_program/ name_of_resource_file" liên quan đến mỗi mục nhập trong getenv ("PATH") là một cách hay để tìm kiếm tài nguyên. Một điều bạn có thể làm là cho phép các thông tin cần thiết được cung cấp trên dòng lệnh hoặc trong một số tệp cấu hình và chỉ thực hiện tìm kiếm nếu cần thiết như một tùy chọn dự phòng.

Sửa
Bây giờ bạn đã tuyên bố lý do của bạn cho việc này, tôi sẽ khuyên bạn chỉ cần sử dụng lớp QSettings từ Qt để biết thông tin cấu hình của bạn, vì nó sử dụng cơ chế tự nhiên ưa thích cho mỗi nền tảng (registry trên Windows, một tệp PLIST trên Mac OS X, cơ sở dữ liệu Gnonf GConf trên Linux). Bạn có thể muốn xem C++ Project Template vì nó sử dụng Qt để làm điều này, và nó cung cấp các tùy chọn dòng lệnh đơn giản để dễ dàng tinh chỉnh các thiết lập cấu hình ("--prefset", "--prefget" và "--preflist" thao tác QSettings).

Điều đó nói rằng, nếu bạn hoàn toàn phải sử dụng tệp cấu hình XML của riêng mình thay vì sử dụng cơ chế gốc ưa thích, tôi khuyên bạn nên đặt cấu hình toàn hệ thống trong " installdir/etc" trong khi đặt thư viện của bạn trong " installdir/lib" đối với một số thư mục cài đặt "installdir", vì đó là vị trí điển hình cho tệp cấu hình trên hệ thống UNIX và " installdir/lib" CHỈ được sử dụng cho tệp thư viện, không dành cho tệp cấu hình và errata khác. Tôi đề nghị bạn đặt một phiên bản dành riêng cho người dùng của tệp cấu hình trong "$ XDG_CONFIG_HOME" (nếu nó được xác định) hoặc trong "$ HOME/.config" (trong đó "$ HOME" là thư mục chính của người dùng).

Khi tìm kiếm tệp cấu hình trên toàn hệ thống, tôi khuyên bạn nên tìm kiếm trong $ XDG_CONFIG_DIRS nếu được xác định; nếu nó không được xác định, sau đó quay trở lại "/ etc/xdg" hoặc tìm kiếm "../etc/name_of_your_program.conf.xml" liên quan đến "$ PATH" và có thể cũng liên quan đến "$ LD_LIBRARY_PATH", " $ DYLD_LIBRARY_PATH "," $ DYLD_FALLBACK_LIBRARY_PATH "), nội dung của" /etc/ld.so.conf "nếu nó tồn tại và nội dung của" /etc/ld.so.conf.d/*.conf "nếu các tệp đó tồn tại, tạm dừng tìm kiếm của bạn ngay sau khi bạn gặp phải tệp cấu hình hợp lệ đầu tiên sẽ là một cách tiếp cận hợp lý.

Tín dụng chuyển đến Roger để chỉ ra số XDG Basedir Spec và để có những phê bình mang tính xây dựng tuyệt vời của anh ấy.

+0

@Roger, cảm ơn một lần nữa. Bạn lại đúng. Có lẽ bạn nên xem xét viết một câu trả lời đầy đủ ... bạn có thể làm một công việc tốt hơn, và tôi sẽ upvote bạn. Trong mọi trường hợp, những lời chỉ trích mang tính xây dựng của bạn khá hữu ích. Cảm ơn bạn. –

+0

Bạn được chào đón, nhưng tôi không thể trả lời như, mặc dù đó là những gì anh ấy thực sự muốn, nó không trả lời những gì anh ta thực sự yêu cầu. (@Steve: Bạn được quyền thay đổi câu hỏi thành "Làm cách nào để tìm cấu hình cho thư viện/chương trình của mình?" Mặc dù ..: P) –

0

giải pháp có thể:

  • Bạn có thể đọc các tập tin /proc/{PID}/mmap để xem danh sách các thư viện chia sẻ. Trong đó {PID} là quá trình pid (bạn có thể lấy nó bằng cách sử dụng getpid()).
  • Gọi công cụ dòng lệnh ldd đối với tệp nhị phân của chương trình (được lưu trữ trong argv[0]).
  • Nếu bạn viết giải pháp từ đầu, hãy xem ldd mã nguồn lệnh từ uClibc cách lấy danh sách các lib được chia sẻ từ một nhị phân elf.
Các vấn đề liên quan