您当前的位置: 首页 >  c++

插件开发

暂无认证

  • 2浏览

    0关注

    492博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

C++-加载指定文件夹的动态链接库-Qt-导出函数申明-修改窗口过程

插件开发 发布时间:2022-04-20 12:39:21 ,浏览量:2

文章目录
    • 1.导出函数声明
    • 2.函数类型和动态加载
    • 3.修改工作目录和动态加载
    • 4.修改DLL搜索路径
    • 5.修改Qt加载动态库路径
    • 6.Qt嵌入目标应用程序
    • 7.修改窗口过程
Qt是一个优秀的C++开源套件,但是发布特定的应用程序时,也存在文件太多的问题,如何开发一个Qt子模块嵌入到目标程序,同时将所有的Qt模块放在一个指定的文件夹,就是一个需要解决的问题。

1.导出函数声明

申明为C兼容的导出函数,然后采用动态加载库的形式动态加载。

#ifdef__cplusplus
#define DLLEXPORT extern "C" _declspec(dllexport)
#else 
#define DLLEXPORT _declspec(dllexport)
#endif
DLLEXPORT BOOL FUN();//这就是要导出函数
2.函数类型和动态加载

动态加载Dll,然后通过GetProcAddress函数来调用对应的API。范例代码如下所示:

typedef void (*ShowMainUIType)(void *hWnd);//申明函数类型
void CallFunc()
{
    HINSTANCE  hDLL = LoadLibraryA("SVGApp13.dll"); //加载dll文件
    //如果加载失败的话, 通过GetLastError()进行获取,看失败原因。
    auto code5 = GetLastError();
    void *pfunc = GetProcAddress(hDLL, "ShowMainUI");
    ShowMainUIType ShowMainUI = (ShowMainUIType)pfunc;//直接使用原工程函数名
    code5 = GetLastError();
    if (ShowMainUI)
    {
        ShowMainUI(hWnd);
    }
}
3.修改工作目录和动态加载

修改应用程序当前目录,有利于控制应用程序的工作目录,主要调用SetCurrentDirectory和GetCurrentDirectory两个函数来切换。

char chCurDir[MAX_PATH] = {0};
GetCurrentDirectory(MAX_PATH, chCurDir);
SetCurrentDirectory(_T("E:\\test\\"));
4.修改DLL搜索路径

修改Dll的搜索路径,该函数影响后续LoadLibraryA类函数寻找dll路径位置:

SetDllDirectoryA("E:/Project/SVGApp13/Win32/Debug");
5.修改Qt加载动态库路径

在QApplication对象申明之前,加载Qt库路径,能够将Qt的动态连接库其它位置的路径包含进来,从而可以将对应的库文件放在子文件夹下。

	QCoreApplication::addLibraryPath(QString::fromLocal8Bit("\\Debug\\"));
	QCoreApplication::addLibraryPath(QString::fromLocal8Bit("\\Debug\\platforms"));
6.Qt嵌入目标应用程序

Qt嵌入目标应用程序作为子窗口,需要替换主应用程序的窗口消息循环,这往往难度较大,或者采用双线程,这样又会导致线程调度等许多问题,除非主程序采用Qt开发,否则不建议采用Qt作为子窗口嵌入,问题还是比较多。建议在比较简单的程序中采用这种方法。

7.修改窗口过程

如果想在宿主应用程序的窗口过程中,夹带一些自定义功能,就需要Hook窗口过程。

//修改窗口过程函数
WNDPROC lpfnOldProc = 0;
LRESULT CALLBACK NewWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
	switch (wMsg) {
		case WM_USER + 99:
		{
			//MessageBoxA(NULL, "窗口过程", "调试", MB_OK);
			g_pACPGMainWindowPlugin->StartSeBiaoMainUI();
			break;
		}
	}
	return CallWindowProc(lpfnOldProc, hWnd, wMsg, wParam, lParam);
}

//修改位置
//lpfnOldProc = (WNDPROC)SetWindowLongPtrA(m_hCDRMainWindow, GWLP_WNDPROC, (DWORD)NewWndProc);
lpfnOldProc = (WNDPROC)SetWindowLongPtrW(m_hCDRMainWindow, GWLP_WNDPROC, (DWORD)NewWndProc);
DWORD code = GetLastError();
关注
打赏
1665481431
查看更多评论
立即登录/注册

微信扫码登录

0.1498s