引子:“在C++builder6中動態調用的方法,(靜態調用實驗沒成功,主要是用implib沒法產生正確的Pinyin.lib,內容缺檔案名稱,一啟動就報找不到檔案,不知道誰可以幫忙解決這個問題)”。
在做《在delphi 7中實現擷取漢字拼音首字母》時,順便試著寫C++builder 6的調用例子,可惜當時靜態調用沒成功,帶中文路徑的implib產生的lib檔案竟然和在根目錄下生產成的lib檔案內容不一樣(用UltraEdit看就知道了),如:"implib E:/拼音首字母/Pinyin.lib E:/拼音首字母/Pinyin.dll" 和 "implib F:/Pinyin.lib F:/Pinyin.dll" 產生的Pinyin.lib就不一樣。前者編譯通過,運行時,報找不到"E CORPORATION .dll",然後訪問地址出錯;後者直接編譯不過,報串連錯誤"[Linker Error] Unresolved external 'GetPinYinLeader' referenced from E:/拼音首字母/UNIT1.OBJ "。
試過其他各種方法產生lib,包括直接修改二進位檔案,都沒成功。最後想到以前有個文章說可以偽造一個有空方法體的dll,產生的lib可直接調用vc產生的dll。
原話是這樣的:“lib可以造假的,比如vc dll有一個函數 你用bcb寫一個dll也有同樣的函數,實現是空的,然後編譯出來
其他使用dll的工程連結lib中這個lib,dll則還是用VC的dll”
參考地址:http://topic.csdn.net/u/20090302/17/99d1fbc5-4be6-4744-96d9-09b16c0d93c3.html
這個拼音庫的協助參考文字是這樣的:
----------------------------------------------------------------------------
本DLL只有兩個函數,函數原型如下:
//獲得拼音
//參數依次為: 拼音緩衝區,要轉換的字元,分隔字元
BOOL WINAPI GetPinYin(PCHAR pBuf,PCHAR pStr,PCHAR pSeparator)
//獲得拼音首字母
//參數依次為: 拼音緩衝區,要轉換的字元
BOOL WINAPI GetPinYinLeader(PCHAR pBuf,PCHAR pStr)
-------------------------------------------------------------------------------------
下面是偽造dll的代碼:
#include <windows.h><br />#pragma argsused</p><p>extern "C" __declspec(dllexport) bool __stdcall WINAPI GetPinYinLeader(PCHAR pBuf,PCHAR pStr);<br />extern "C" __declspec(dllexport) bool __stdcall WINAPI GetPinYin(PCHAR pBuf,PCHAR pStr,PCHAR pSeparator);</p><p>int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)<br />{<br /> return 1;<br />}<br />/<br />bool __stdcall WINAPI GetPinYinLeader(PCHAR pBuf,PCHAR pStr)<br />{<br /> return true;<br />}<br />bool __stdcall WINAPI GetPinYin(PCHAR pBuf,PCHAR pStr,PCHAR pSeparator)<br />{<br /> return true;<br />}
靜態調用代碼:
extern "C" __declspec(dllimport) bool __stdcall GetPinYinLeader(char * buf,char * input);<br />extern "C" __declspec(dllimport) bool __stdcall GetPinYin(char * buf,char * input,char * sp);<br />//---------------------------------------------------------------------------<br />__fastcall TForm1::TForm1(TComponent* Owner)<br /> : TForm(Owner)<br />{<br />}</p><p>void __fastcall TForm1::btn1Click(TObject *Sender)<br />{</p><p> char cbuf[256]={0};<br /> memset(cbuf,0,sizeof(cbuf));<br /> char * cinput;<br /> cinput = (Trim(edt1->Text)).c_str();<br /> //<br /> GetPinYinLeader(cbuf,cinput);<br /> edt2->Text = (AnsiString)cbuf;</p><p>}
經過測試,結論:是可以這樣做的,得出的結果跟動態調用一樣。