2009-08-05 26 views
25

Tôi cần trợ giúp về viết mã đa nền tảng; không phải là một ứng dụng, mà là một thư viện.C++ Cross Platform Dynamic Libraries; Linux và Windows

Tôi đang tạo một thư viện tĩnh và động với hầu hết các phát triển được thực hiện trong Linux, tôi đã có thư viện tĩnh và chia sẻ được tạo trong Linux nhưng bây giờ muốn tạo phiên bản Windows của thư viện tĩnh và động trong biểu mẫu của .lib.dll sử dụng cùng một mã nguồn.

Điều này có khả thi không? Tôi hơi lo lắng vì tôi nhận thấy việc tạo các tệp Windows .dll bắt buộc bằng cách sử dụng _dllspec hoặc một cái gì đó tương tự trong mã nguồn của bạn.

Nếu không thì bất kỳ ai cũng có thể tư vấn cho tôi giải pháp tốt nhất và nhanh nhất để lấy mã được biên dịch trên Windows. Tôi không cần phải làm việc biên dịch dưới Linux Tôi rất vui khi làm điều đó trực tiếp trong Windows. Ngoài ra tôi đang sử dụng hai thư viện bên ngoài được thúc đẩy và Xerces XML mà tôi đã cài đặt trên cả hai cửa sổ của tôi và hệ thống Linux để hy vọng họ không phải là một vấn đề.

Điều tôi thực sự muốn là có một bản sao mã nguồn duy nhất có thể được biên dịch trong cả Linux và Windows để tạo các thư viện cụ thể cho mỗi nền tảng. Tôi không thực sự quan tâm nếu tôi phải chỉnh sửa mã của tôi ủng hộ Windows hoặc Linux miễn là tôi có thể có một bản sao mã nguồn duy nhất.

+0

Biên dịch chéo thường đề cập đến phần mềm xây dựng trên một nền tảng để chạy trên nền tảng khác. Vì bạn nói rằng bạn muốn mã nguồn có thể được biên dịch trên cả Linux và Windows, thì câu hỏi của bạn thực sự là viết về một nền tảng mã nguồn di động đa nền tảng hơn là về việc biên dịch chéo. –

+0

GIYF Trên thực tế, trong trường hợp này, libtool là bạn của bạn ... –

+0

Trong khi chờ đợi câu trả lời, hãy xem CMake: http://www.cmake.org/ – Pete

Trả lời

18

Nói chung, có hai vấn đề bạn cần phải quan tâm đến:

  1. Yêu cầu đó, trên Windows, DLL của bạn xuất khẩu một cách rõ ràng biểu tượng được hiển thị cho thế giới bên ngoài (thông qua __declspec(dllexport), và
  2. có khả năng duy trì hệ thống xây dựng (lý tưởng, không cần phải duy trì một makefile riêng và Microsoft Visual C++ Dự án/giải pháp)

Đối với người đầu tiên, bạn sẽ cần phải tìm hiểu về __declspec(dllexport). Mở Windows chỉ các dự án, thông thường điều này được thực hiện theo cách tôi mô tả trong câu trả lời của tôi cho this question. Bạn có thể mở rộng thêm một bước nữa bằng cách đảm bảo rằng biểu tượng xuất của bạn (chẳng hạn như MY_PROJECT_API) được định nghĩa nhưng mở rộng thành không có gì khi xây dựng cho Linux. Bằng cách này, bạn có thể thêm các biểu tượng xuất khẩu vào mã của bạn khi cần thiết cho Windows mà không ảnh hưởng đến việc xây dựng linux.

Thứ hai, bạn có thể điều tra một số loại hệ thống tạo nền tảng đa nền tảng.

Nếu bạn cảm thấy thoải mái với bộ công cụ GNU, bạn có thể muốn điều tra libtool (có thể kết hợp với automake và autoconf). Các công cụ này được hỗ trợ nguyên bản trên Linux và được hỗ trợ trên Windows thông qua Cygwin hoặc MinGW/MSYS. MinGW cũng cung cấp cho bạn tùy chọn biên dịch chéo, tức là, xây dựng các tệp nhị phân Windows gốc của bạn trong khi chạy Linux. Hai tài nguyên tôi thấy hữu ích trong việc điều hướng các Autotools (bao gồm cả libtool) là "Autobook" (cụ thể là phần trên DLLs and Libtool) và Alexandre Duret-Lutz's PowerPoint slides.

Như những người khác đã đề cập, CMake cũng là một tùy chọn, nhưng tôi không thể tự mình nói.

+0

cảm ơn, tôi đã làm một số google tìm kiếm và đoán tôi đã tìm kiếm những điều sai trái, libtool có âm thanh thú vị và có lẽ cmake như ai đó đã đề cập ở trên. Tôi là loại mới để linux vì vậy công cụ này không nhanh chóng đổ chuông: p –

9

Bạn có thể dễ dàng thực hiện điều đó với # ifdef's. Trên Windows _WIN32 nên được định nghĩa bởi trình biên dịch (ngay cả đối với 64 bit), do đó, mã như

#ifdef _WIN32 
# define EXPORTIT __declspec(dllexport) 
#else 
# define EXPORTIT 
#endif 

EXPORTIT int somefunction(); 

sẽ hoạt động OK cho bạn.

+0

hmm yeah Tôi nghĩ về điều đó, tôi sẽ xem nó sẽ như thế nào, có thể sử dụng nó như là phương sách cuối cùng của tôi nếu tôi không có may mắn với các công cụ trên –

+0

@iQ: Bạn sẽ vẫn phải làm điều này, ngay cả với các công cụ trên. Họ không xử lý việc xuất khẩu cho bạn, họ chỉ giấu một số khác biệt giữa quá trình xây dựng trên các nền tảng khác nhau. –

+0

vâng tôi đoán quyền của bạn, tôi sẽ phải sử dụng macro. Tôi hiện đang cố gắng để xem xét codeblocks mà tôi nghĩ rằng nó có thể tự động xác định một tập tin .def cho bạn mặc dù tôi không biết làm thế nào tốt hay xấu đó là. Tôi sẽ phải thử nghiệm một chút. –

7

Có lẽ sẽ tốt hơn nếu bạn Thêm extern "C" !!!,

/* nộp CMakeLists.txt */

SET (LIB_TYPE SHARED) 

ADD_LIBRARY(MyLibrary ${LIB_TYPE} MyLibrary.h) 

/* tập tin MyLibrary.h */

#if defined(_WIN32) || defined(__WIN32__) 

    #if defined(MyLibrary_EXPORTS) // add by CMake 

    #define MYLIB_EXPORT extern "C" __declspec(dllexport) 
    #else 

    #define MYLIB_EXPORT extern "C" __declspec(dllimport) 

    #endif /* MyLibrary_EXPORTS */ 

#elif defined(linux) || defined(__linux) 

#define MYLIB_EXPORT 

#endif 


MYLIB_EXPORT inline int Function(int a) 

{ 
    return a ; 
} 
+1

Vì tình yêu của thần, xin vui lòng, sử dụng một định dạng đẹp hơn! – tstenner

+0

@tstenner bạn muốn nói rằng bạn không chỉ hoàn toàn TÌNH YÊU khi mọi người tạo nên phong cách định dạng của riêng họ khi đang nhập khi họ đang nhập mã của họ? :) –

+0

@tstenner đã đồng ý .. "định dạng" này quá .. làm thế nào tôi có thể nói .. –

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