MFC应用程序和共享库
MFC app and shared libs
我有一个应用程序,似乎已经写在MFC(进程黑客和DependencyWalker显示链接到MFC90)。
另外,在安装路径中有一个库(FTD2XX)。但是DependencyWalker不会显示lib的MFC90链接并显示:
SetupAPI.dll
KERNEL32.dll
USER32.dll
ADVAPI32.dll
lib是在什么框架下构建的?我没有MFC方面的经验。我没有信息在它的编译器,如果vc++库可以用来链接与MFC应用程序。
如果你想记录对dll的调用,最好的方法是编写一个代理dll (dll重定向)。但是对于,你必须知道你要覆盖的函数的签名(语法),即参数的确切数量,它们的类型和返回类型等。如果我能假设你能以某种方式找到ftd2xx.dll中所有函数的签名,那么完成它就很简单了。
获取dll函数和序数:为此,只需使用Visual Studio自带的dumpbin.exe(通过运行Visual Studio命令提示符使用它)
dumpbin.exe/exports {yourpath}ftd2xx.dll> ftd2xx.txt
现在您的ftd2xx.txt包含了ftd2xx.dll中的所有函数名和序号。你甚至可以使用依赖项跟踪器来导出和获取这个列表。
创建自己的名为ftd2xx.dll的dll:打开Visual Studio,选择vc++>> Win32>> Win32 Project>> 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;
}
注意,在LoadLibraryA()调用中,原始dll被称为ftd2xx_.dll。因此,将原始dll重命名为ftd2xx_.dll或您想要的任何名称。构建代理dll代码并将代理dll (ftd2xx.dll)带到原始ftd2xx.dll所在的路径。现在,您的应用程序将像往常一样调用ftd2xx.dll(代理),但ftd2xx.dll将在内部调用原始dll ftd2xx_.dll。
Update # 1: 我一直提到你需要知道你试图覆盖的函数的签名,幸运的是,我刚刚在linux版本的驱动程序中找到了ftd2xx.h文件。
ftd2xx Linux版本
下载libftd2xx-i386-1.3.6从上面的链接中提取ftd2xx.h文件并将其解压缩到一个文件夹(我使用的是7zip),进一步提取.tar文件以获得发布文件夹,您将在"发布"文件夹中找到ftd2xx.h文件。好了,现在你得到了dll的完整函数签名,并且知道如何编写代理dll。好运。
- Qt - 共享同一数据库的应用程序
- 使用 IPC 共享内存的应用程序是否可以访问彼此的代码?
- 在 API 和应用程序线程之间共享数据
- 将函数从控制台应用程序移动到共享库项目似乎会带来不相关的编译错误
- 共享对象与提升program_options静态链接;应用程序链接共享
- Qt应用程序在运行时找不到共享库
- 尝试使用共享库部署QT应用程序时出错
- 如何将 #defines 从 c++ 共享库导出到应用程序
- 在Linux中使用gcc 4.1编译的C++03应用程序中使用C++11共享库
- 在应用程序和驱动程序之间共享内存
- 在Windows 8上共享应用程序URI方案注册
- SFML2 应用程序找不到共享对象
- VC++和Qt应用程序之间使用共享内存进行通信
- 管理多线程应用程序中的共享变量
- 交叉编译用于树莓派的QT应用程序-无法打开共享对象文件
- 如何与其他应用程序共享 HGLOBAL?
- 获取包含共享库的c++应用程序的调用堆栈
- 带有API的WinRT应用程序,该应用程序使用共享的MFC dll
- 在两个单独的应用程序之间共享 dll 中的堆内存
- 使用共享库在 Ubuntu 上部署 Qt 应用程序二进制文件