2015-10-05 108 views
-2

我有一個似乎已經寫在MFC(過程黑客和DependencyWalker顯示鏈接到MFC90)的應用程序。MFC應用程序和共享庫

另外,安裝路徑中有一個庫(FTD2XX)。但是DependencyWalker將不顯示MFC 90鏈接的lib和顯示:

SetupAPI.dll 
KERNEL32.dll 
USER32.dll 
ADVAPI32.dll 

在lib是建立什麼樣的框架? 我沒有MFC的經驗。我的編譯器中沒有信息,如果可以使用VC++庫來鏈接MFC應用程序。

+0

FTD2xx沒有寫在MFC中,如果這是你問的。 http://sourceforge.net/projects/ftd2xx/你的問題對我來說不是很清楚。 –

+0

@Bancila我想寫一個FTD2XX的副本。但是我不知道我應該在哪個框架中編寫這個框架? – Mosi

+0

我想創建一個庫並將其替換爲FTD2XX來記錄應用程序的函數調用。所以我需要知道在什麼框架下我應該這樣做 – Mosi

回答

1

如果你想記錄去往dll的調用,最好的方法是編寫一個代理dll(一個dll重定向)。但對於你必須知道函數的簽名(語法),你準備覆蓋,參數,它們的類型即確切數量和返回類型等,如果我可以假設你在某種程度上可以找出簽名ftd2xx.dll中的所有函數,那麼完成它只是簡單的。

獲取DLL函數和序數詞: 對於本只使用自帶DUMPBIN.EXE與Visual Studio(通過運行Visual Studio的命令提示符下使用)

DUMPBIN.EXE /出口{yourpath} \ ftd2xx.dll> ftd2xx.txt

現在您的ftd2xx.txt包含ftd2xx.dll的所有函數名和序號。你甚至可以使用你的依賴walker導出並獲取這個列表。

創建您自己的DLL名爲ftd2xx.dll: 打開Visual Studio,選擇VC++ >> >> Win32的Win32項目>> DLL(與出口符號選項),最後使用#pragma指令來聲明全部出口原您的DLL的代碼中的DLL功能,如下面,

//#pragma comment (linker, "/export:<function>=<origdll_name>.<function>,@<ordinal_number>") 

#pragma comment (linker, "/export:FT_Open=ftd2xx_.FT_Open,@1") 
#pragma comment (linker, "/export:FT_Close=ftd2xx_.FT_Close,@2") 
// : 
// : 
// : 
// delcare all your exported functions here with ordinal number 
// : 
// : 
BOOL APIENTRY DllMain(HMODULE hModule, 
         DWORD ul_reason_for_call, 
         LPVOID lpReserved 
        ) 
{ 
} 

現在,你需要編寫自己的功能,它可以裝作ftd2xx.dll的原始功能,當應用程序調用ftd2xx的原有功能,將被調用。 DLL。下面的代碼只是解釋它是如何工作的。正如我前面說過的,你需要知道你想覆蓋的dll函數的確切簽名(重定向)。並且請記住,無論您想做什麼,都需要調用原始函數,否則可能會導致應用程序出現意外行爲。

假設FT_Close()函數不接受任何參數並返回void,我只是舉個例子,我用代理NewFT_Close()函數重寫ftd2xx.dll的FT_Close()函數。請注意,如果您重寫了一個函數,然後將其從#pragma指令中刪除並將其添加到.def文件中(將新的ftd2xx.def文件添加到您的項目並聲明您的新函數,如下所示)。

DEF文件的例子

LIBRARY ftd2xx.dll 
EXPORTS 
FT_Close = NewFT_Close @2 

DLL的代碼示例

HINSTANCE hInstance = NULL;  // handle to ftd2xx.dll 
FARPROC  fpFTClose = {NULL};  // function pointer to hold original function address 

extern "C" void __stdcall NewFT_Close() 
{ 
    // This is our proxy function for FT_Close() 
    // Do whatever you want to do here and the 
    // finally call the original FT_Close() using 
    // the function pointer we got from GetProcAddress() 
    typedef void (__stdcall *PFTCLOSE)(); 
    PFTCLOSE pFc = (PFTCLOSE)fpFTClose; 
    if(pFc) pFc(); 
} 

BOOL APIENTRY DllMain(HMODULE hModule, 
         DWORD ul_reason_for_call, 
         LPVOID lpReserved 
        ) 
{ 
    switch (ul_reason_for_call) 
    { 
     case DLL_PROCESS_ATTACH: 
      // Load the original dll in to the memory and get the handle 
      hInstance = LoadLibraryA("ftd2xx_.dll"); 
      if(!hInstance) return FALSE; 
      // Get the address of the function to be overriden 
      fpFTClose = GetProcAddress(hInstance,"FT_Close"); 
     case DLL_THREAD_ATTACH: 
     case DLL_THREAD_DETACH: 
     case DLL_PROCESS_DETACH: 
      // Our dll is getting unloaded from the application, unload original as well 
      FreeLibrary(hInstance); 
      break; 
    } 
    return TRUE; 
} 

注意,原始DLL在LoadLibraryA稱爲ftd2xx_.dll()調用。因此,將原始dll重命名爲ftd2xx_。或者任何你想要的名字。建立你的代理dll代碼,並把你的代理dll(ftd2xx.dll)放到原來的ftd2xx.dll所在的路徑。現在,您的應用程序將像往常一樣調用ftd2xx.dll(代理),但ftd2xx.dll將在內部調用原始的dll ftd2xx_.dll。

更新#1: 我一直提的是,你需要知道你正在試圖重寫功能的簽名,並靠運氣我剛剛發現在驅動程序的Linux版本的ftd2xx.h文件。

Linux version of ftd2xx

從上面的鏈接下載libftd2xx-i386-1.3.6.tgz文件,並將其解壓到一個文件夾(我用7zip的),進一步提取.tar文件得到釋放文件夾,你」在「release」文件夾中找到ftd2xx.h文件。你去了,現在你有了完整的dll函數簽名,並且你知道如何編寫代理dll。祝你好運。

+0

我創建了代理DLL,但應用程序不啓動,不會拋出任何錯誤消息。我是否需要導出所有功能或僅需要的功能? – Mosi

+0

您需要從原始dll導出所有功能。使用dumpbin.exe將所有這些文件轉換爲文本文件,並對除了要覆蓋的所有函數執行#pragma鏈接。您要覆蓋的功能將按照答案中的說明轉到DEF文件。 –

+0

原始dll的編譯器版本是否必須與我的代理dll相同? – Mosi

相關問題