2009-01-14 33 views
7

Tôi có một ứng dụng và một số plugin trong các tệp DLL. Các plugin sử dụng các biểu tượng từ ứng dụng thông qua thư viện xuất. Các ứng dụng liên kết trong một số thư viện tĩnh và đây là nơi mà hầu hết các biểu tượng đến từ. Điều này làm việc tốt miễn là ứng dụng sử dụng một biểu tượng. Nếu biểu tượng không được sử dụng ở đó, tôi nhận được các lỗi liên kết khi biên dịch DLL.Bắt buộc xuất biểu tượng bằng MSVC

Làm cách nào để bắt buộc xuất biểu tượng chỉ được sử dụng trong plugin?

Để kích hoạt việc xuất khẩu Tôi đã thử một cái gì đó như thế này:

class MyClassExporter 
    { 
     MyClass mInstance; 
    public: 
     MyClassExporter() {} 
    }; 
    static MyClassExporter TheMyClassExporter; 

tại một trong những libs tĩnh ứng dụng được làm bằng để buộc xuất khẩu, mà không làm việc.

Để trả lời cho Greg (cảm ơn câu trả lời) và để làm rõ: Lớp tôi muốn ép xuất là MyClass (có __declspec (...) được xác định, tùy thuộc vào thời điểm tôi muốn xuất hoặc nhập) . MyClassExport là nỗ lực của tôi để buộc việc đưa vào các biểu tượng không được sử dụng (về mặt ứng dụng) vào ứng dụng. Tôi muốn 'chạm' các biểu tượng để người liên kết nhận ra chúng như được sử dụng và đưa chúng vào ứng dụng để nó có thể lần lượt xuất chúng sang các plugin của tôi. Liên kết các libs tĩnh vào các plugins không phải là một tùy chọn, vì chúng chứa các singletons sẽ được nhân đôi (mỗi ứng dụng và DLL có bản sao riêng của các biến tĩnh).

Trả lời

3

Bạn có thể muốn nhìn vào __declspec (xuất khẩu/nhập khẩu)

#ifdef DLL_EXPORTING 
#define WHDLL __declspec(dllexport) 
#else 
#define WHDLL __declspec(dllimport) 
#endif 

Khi liên kết mô-đun tĩnh thành một dll nó sẽ chỉ mang lại trong các mã được sử dụng. Tôi chưa bao giờ nhập nội dung từ một lib tĩnh để chỉ cần xuất lại nó.
Có lẽ bạn chỉ cần đánh dấu nó là có thể xuất được trong dll khi biên dịch lib tĩnh.

Nhưng điều đó nhắc tôi về việc đưa container std vào các lớp xuất khẩu và sử dụng một số thủ thuật trong msvc để xuất khẩu 'instance' của container chuyên biệt. các mẫu mã cũng tương tự như mã tĩnh của bạn (trong suy nghĩ của tôi)

ví dụ mà không có mẫu bạn nhận được cảnh báo các mẫu mã không được xuất khẩu để hỗ trợ các lớp - đây là MSVC cụ thể từ các hiểu biết của tôi

template class DLL_EXPORTING std::auto_ptr<wxCursor>; 
class DLL_EXPORTING imageButton : public wxWindow 
{ 
    std::auto_ptr<wxCursor> m_Cursor; 
}; 
+0

Tôi cần nhập từ libs tĩnh và xuất sang các plugin vì tôi có các phần tử đơn trong đó sẽ bị trùng lặp nếu tôi liên kết chúng vào tệp DLL (DLL và ứng dụng có biến tĩnh riêng). Câu đầu tiên của bạn giải thích vấn đề: Tôi đang tìm một cách để ép buộc sự bao gồm. – torque

4

Chỉ thị /INCLUDE có thể được sử dụng để buộc trình liên kết MSVC bao gồm một biểu tượng. Ngoài ra, có thể sử dụng /OPT:NOREF để vô hiệu hóa việc xóa các biểu tượng không sử dụng nói chung.

Cách tiếp cận chung là tạo một hàm không sử dụng duy nhất tham chiếu đến tất cả các đối tượng được xuất cho các plugin của bạn. Sau đó, bạn chỉ cần một đơn/INCLUDE chỉ thị cho chức năng đó.

+0

Đã thử cách này, nhưng không hoạt động - các biểu tượng có phải là 'trang trí' không? Chúng có thể chứa không gian tên không? – xtofl

+0

Đã làm việc với/OPT: NOREF? Nếu không, bạn có thể có một vấn đề khác hoàn toàn ... –

+0

Biểu tượng cần phải được chỉ định trong biểu mẫu trang trí –

2

gì tôi đã cố gắng ra để giải quyết này là thế này:

  1. xây dựng một thư viện tĩnh với chức năng void afunction(int).
  2. tạo dll, được liên kết với lib tĩnh, xuất afunction.
  3. xây dựng một exe, sử dụng biểu tượng afunction.

Làm cách nào?Vì trình liên kết có thể được yêu cầu xuất các hàm bằng cách sử dụng chỉ thị __declspec(dllexport), một dll không cần nhiều hơn khai báo một biểu tượng được xuất khẩu như vậy.

Các lib có tiêu đề "afunction.h" và một file cpp đi kèm có chứa các cơ quan chức năng:

// stat/afunction.h 
namespace static_lib { void afunction(int); } 


// stat/afunction.cpp 
#include "afunction.h" 
namespace static_lib { void afunction(int){ } } 

Các dll có bao gồm tập tin "indirect.h", có chứa các khai báo của hàm để được xuất khẩu. Các dll có một phụ thuộc thời gian liên kết đến lib tĩnh. (Linker lựa chọn: Input/Dependencies bổ sung: "static_library.lib")

// dll/indirect.h 
namespace static_lib { 
    __declspec(dllexport) void afunction(int); 
} 

Các thực thi chỉ có các tập tin gián tiếp bao gồm:

#include <dll/indirect.h> 
int main() { static_lib::afunction(1); } 

Và đoán những gì? Nó biên dịch, liên kết và thậm chí chạy!

1

Có một số thảo luận về vấn đề này trên MSDN khá hữu ích. Khi nó quay ra,/OPT: NOREF không đặc biệt hữu ích trong trường hợp này./INCLUDE có thể làm việc nhưng khó có thể tự động tìm ra những gì cần phải có/INCLUDEd. Không may là không có viên đạn bạc.

http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/2aa2e1b7-6677-4986-99cc-62f463c94ef3

+0

Chủ đề đó có câu trả lời, nhưng không rõ ràng và có một nhận xét gây hiểu lầm cho biết điều này không hoạt động với VS2005, khi thực tế nó có. Xem câu trả lời của tôi cho câu hỏi SO này để biết chi tiết ... –

2

Các "Sử dụng thư viện phụ thuộc đầu vào" tùy chọn hiện các trick trong VS2005!

Tùy chọn này có thể được tìm thấy trong Thuộc tính cấu hình -> Trình liên kết -> Chung -> Sử dụng đầu vào phụ thuộc thư viện. Đặt thành "true" để buộc liên kết trong TẤT CẢ các ký hiệu & mã được khai báo trong mọi LIB được chỉ định làm đầu vào cho dự án.

Bạn có thể thực hiện các thao tác sau để lấy biểu tượng xuất từ ​​tệp DLL: xác định LIB_EXPORTS trong dự án thư viện và không có gì trong dự án DLL hoặc dự án khách DLL.

#ifdef LIB_EXPORTS 
#define DLLAPI __declspec(dllexport) 
#else 
#define DLLAPI __declspec(dllimport) 
#endif 

Bật ra không cần # bao gồm bất kỳ tiêu đề nào từ dự án LIB khi biên dịch dự án DLL; chỉ cần chỉ định LIB làm đầu vào liên kết. Tuy nhiên, nếu bạn cần sử dụng mã LIB từ bên trong DLL, bạn sẽ cần phải #define DLLAPI làm macro trống; đặt (các) ký hiệu thành dllexport hoặc dllimport sẽ tạo ra lỗi hoặc cảnh báo tương ứng.

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