標籤:http io os 使用 ar for 檔案 sp 問題
原工程在VS2005下建立,後遷移到Eclipse CDT 3.3.2 + MingGW下,並增加makefile檔案。
原VS2005下工程Sample,實現了對類SampleClass封裝,產生Sample.dll檔案。工程源碼檔案包括stdafx.h, stdafx.cpp, targetver.h, dllmain.cpp, Sample.def, Sample.h, Sample.cpp, SampleClass.h, SampleClass.cpp。其中stdafx.h, stdafx.cpp, targetver.h用來建立先行編譯標頭檔SampleClass.pch和先行編譯類型檔案StdAfx.obj;dllmain.cpp, Sample.def為載入DLL入口函數檔案和模組定義檔案;SampleClass.h, SampleClass.cpp對類SampleClass進行了聲明和定義;Sample.h, Sample.cpp則定義DLL應用程式的匯出函數。
首先在Eclipse下建立工程Sample,然後利用import功能,將VS2005下原工程的*.h, *.cpp, *.def, *.txt檔案匯入到Sample工程中。具體操作可參考IBM Developworks的《將Visual Studio C和C++ 項目遷移到 Eclipse CDT》(http://www.ibm.com/developerworks/cn/opensource/os-ecl-vscdt/)。另需要注意到是,該連結文章中使用IDE為VC6可匯出並修改makefile,而VS2005已經不提供匯出makefile檔案功能。
接下來,編寫了makefile檔案(因DLL調用編譯問題,需自己添加g++ 命令)。其中實現了多檔案(Sample.cpp和SampleClass.cpp)的編譯連結,解決方案有兩個:其一是在Sample.cpp中include “SampleClass.cpp”,作為一個檔案編譯;其二是在makefile中添加g++參數先分別編譯兩個cpp檔案,再連結產生DLL。本文用到的是第二種方法。
用到的g++參數說明如下(注意g++前均為tab鍵非空格):
-shared參數用來建立共用庫,在windows中為dll。其中要注意”-o Sample.dll Sample.o SampleClass.o”中兩個.o檔案都必須包含,否則報錯undefined reference to `SampleClass::CheckLicense(char const*)‘等;
-Wl,--out-implib 這個參數主要是產生.a這個檔案;-Wl等待下一條資訊進行串連,--out-implib是給串連程式ld使用的,用於建立要串連dll需要的import library;
-DFILTERPLUGIN_EXPORTS來設定宏FILTERPLUGIN_EXPORTS。編譯時間將手動設定FILTERPLUGIN_EXPORTS宏,這時候宏FILTERPLUGIN_API被設定成__declspec(dllexport)。這樣GCC就能編譯這個DLL。當從可執行檔中調用DLL時,FILTERPLUGIN_EXPORTS宏沒有被設定,FILTERPLUGIN_API宏被設定成__declspec(dllimport), 它將使函數在調用範圍內可見。__declspec(dllexport)和__declspec(dllimport)是用來建立DLL的宏。
如需建立exe可執行程式,需增加
Sample.exe: Sample.o Sample.dll
g++ -o Sample.exe Sample.o -L./ -lmessage
其中-L 指定串連庫路徑,-lmessage (or -l message) 指定DLL的import library。
具體資訊可參見Minimalist GNU for Windows的A sample DLL (http://www.mingw.org/MinGWiki/index.php/sample%20DLL?PHPSESSID=abce11154a632520eb),以及GNU make手冊。
-----------------
makefile檔案如下:
CXXFLAGS = -O2 -g -Wall -fmessage-length=0
OBJS = Sample.o SampleClass.o dllmain.o stdafx.o
LIBS =
TARGET = Sample.dll
$(TARGET): $(OBJS)
$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
all: $(TARGET)
# rm for LINUX/UNIX, while del for DOS
clean:
rm -f $(OBJS) $(TARGET)
del *.o
del Sample.dll
Sample.dll: Sample.o SampleClass.o
g++ -shared -o Sample.dll Sample.o SampleClass.o -Wl,--out-implib,libmessage.a
Sample.o: Sample.cpp Sample.h SampleClass.h
g++ -c -DFILTERPLUGIN_EXPORTS Sample.cpp
SampleClass.o: SampleClass.cpp SampleClass.h
g++ -c SampleClass.cpp
dllmain.o: dllmain.cpp Sample.h
g++ -c dllmain.cpp
stdafx.o: stdafx.cpp stdafx.h targetver.h
g++ -c stdafx.cpp
VS2005工程遷移到Eclipse CDT