qtplugins

This commit is contained in:
恍兮惚兮 2024-03-28 00:03:55 +08:00
parent 07083bd5ec
commit 6834f6809d
2 changed files with 87 additions and 21 deletions

View File

@ -4,7 +4,7 @@ target_precompile_headers(ToClipboard REUSE_FROM pch)
set_target_properties(ToClipboard PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugin${bitappendix}")
endif()
if(0) #pluginmanager->QtLoadLibrarys
include(QtUtils.cmake)
msvc_registry_search()
if(Qt5_DIR)
@ -16,3 +16,4 @@ if(Qt5_DIR)
target_link_libraries(QtLoader Qt5::Widgets Qt5::Core)
set_target_properties(QtLoader PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugin${bitappendix}")
endif()
endif()

View File

@ -25,13 +25,88 @@ std::optional<std::wstring>SelectFile(HWND hwnd,LPCWSTR lpstrFilter){
}
else return {};
}
typedef HMODULE*(*QtLoadLibrary_t)(LPWSTR*,int);
QtLoadLibrary_t loadqtloader(const std::filesystem::path&pluginpath){
auto QtLoaderPath=pluginpath/"QtLoader.dll";
auto helper=LoadLibrary(QtLoaderPath.c_str());
if(helper==0)return 0;
auto QtLoadLibrary = (QtLoadLibrary_t)GetProcAddress(helper, "QtLoadLibrary");
return QtLoadLibrary;
#ifndef _WIN64
#define THISCALL __thiscall
#define _CDECL __cdecl
#define fnQString_fromStdWString "?fromStdWString@QString@@SA?AV1@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z"
#define fnQCoreApplication_addLibraryPath "?addLibraryPath@QCoreApplication@@SAXABVQString@@@Z"
#define fnQString_dtor "??1QString@@QAE@XZ"
#define fnQApplication_ctor "??0QApplication@@QAE@AAHPAPADH@Z"
#define fnQFont_ctor "??0QFont@@QAE@ABVQString@@HH_N@Z"
#define fnQApplication_setFont "?setFont@QApplication@@SAXABVQFont@@PBD@Z"
#define fnQFont_dtor "??1QFont@@QAE@XZ"
#define fnQApplication_exec "?exec@QApplication@@SAHXZ"
#define fnQApplication_dtor "??1QApplication@@UAE@XZ"
#else
#define THISCALL __fastcall
#define _CDECL __fastcall
#define fnQString_fromStdWString "?fromStdWString@QString@@SA?AV1@AEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z"
#define fnQCoreApplication_addLibraryPath "?addLibraryPath@QCoreApplication@@SAXAEBVQString@@@Z"
#define fnQString_dtor "??1QString@@QEAA@XZ"
#define fnQApplication_ctor "??0QApplication@@QEAA@AEAHPEAPEADH@Z"
#define fnQFont_ctor "??0QFont@@QEAA@AEBVQString@@HH_N@Z"
#define fnQApplication_setFont "?setFont@QApplication@@SAXAEBVQFont@@PEBD@Z"
#define fnQFont_dtor "??1QFont@@QEAA@XZ"
#define fnQApplication_exec "?exec@QApplication@@SAHXZ"
#define fnQApplication_dtor "??1QApplication@@UEAA@XZ"
#endif
std::vector<HMODULE> QtLoadLibrarys(std::vector<std::wstring>&collectQtplugs)
{
std::vector<HMODULE> modules;
auto Qt5Widgets=LoadLibrary(L"Qt5Widgets.dll");
auto Qt5Gui=LoadLibrary(L"Qt5Gui.dll");
auto Qt5Core=LoadLibrary(L"Qt5Core.dll");
if(Qt5Core==0||Qt5Gui==0||Qt5Widgets==0)return {};
auto QString_fromStdWString=GetProcAddress(Qt5Core,fnQString_fromStdWString);
auto QCoreApplication_addLibraryPath=GetProcAddress(Qt5Core,fnQCoreApplication_addLibraryPath);
auto QString_dtor=GetProcAddress(Qt5Core,fnQString_dtor);
auto QApplication_ctor=GetProcAddress(Qt5Widgets,fnQApplication_ctor);
auto QFont_ctor=GetProcAddress(Qt5Gui,fnQFont_ctor);
auto QFont_dtor=GetProcAddress(Qt5Gui,fnQFont_dtor);
auto QApplication_setFont=GetProcAddress(Qt5Widgets,fnQApplication_setFont);
auto QApplication_exec=GetProcAddress(Qt5Widgets,fnQApplication_exec);
auto QApplication_dtor=GetProcAddress(Qt5Widgets,fnQApplication_dtor);
if(QString_fromStdWString==0||QCoreApplication_addLibraryPath==0||QString_dtor==0||QApplication_ctor==0||QFont_ctor==0||QFont_dtor==0||QApplication_setFont==0||QApplication_exec==0||QApplication_dtor==0)return {};
auto mutex=CreateSemaphoreW(0,0,1,0);
std::thread([=,&modules](){
static void* qapp; //必须static
void* qstring;
void* qfont;
for(int i=0;i<collectQtplugs.size();i++){
auto dirname=std::filesystem::path(collectQtplugs[i]).parent_path().wstring();
((void* (_CDECL*)(void*,void*))QString_fromStdWString)(&qstring,&dirname);
((void(_CDECL *)(void*))QCoreApplication_addLibraryPath)(&qstring);
((void(THISCALL*)(void*))QString_dtor)(&qstring);
//QCoreApplication_addLibraryPath(QString_fromStdWString(std::filesystem::path(collectQtplugs[i]).parent_path()));
}
int _=0;
((void*(THISCALL*)(void*,int*,char**,int))QApplication_ctor)(&qapp,&_,0,331266);
std::wstring font=L"MS Shell Dlg 2";
((void* (_CDECL*)(void*,void*))QString_fromStdWString)(&qstring,&font);
((void*(THISCALL*)(void*,void*,int,int,bool))QFont_ctor)(&qfont,&qstring,10,-1,0);
((void(_CDECL*)(void*,void*))QApplication_setFont)(&qfont,0);
((void(THISCALL*)(void*))QFont_dtor)(&qfont);
((void(THISCALL*)(void*))QString_dtor)(&qstring);
for(int i=0;i<collectQtplugs.size();i++){
modules.push_back(LoadLibrary(collectQtplugs[i].c_str()));
}
ReleaseSemaphore(mutex,1,0);
((void(*)())QApplication_exec)();
((void(THISCALL*)(void*))QApplication_dtor)(&qapp);
}).detach();
WaitForSingleObject(mutex,INFINITE);
return modules;
}
void Pluginmanager::loadqtdlls(std::vector<std::wstring>&collectQtplugs){
if(collectQtplugs.size()==0)return;
@ -45,19 +120,9 @@ void Pluginmanager::loadqtdlls(std::vector<std::wstring>&collectQtplugs){
}
SetEnvironmentVariableW(L"PATH",envs.c_str());
auto QtLoadLibrary = loadqtloader(pluginpath);
if(!QtLoadLibrary){
MessageBoxW(host->winId,CantLoadQtLoader,L"Error",0);
return ;
}
std::vector<wchar_t*>saves;
for(auto&p:collectQtplugs){
auto str=new wchar_t[p.size()+1];
wcscpy(str,p.c_str());
saves.emplace_back(str);
}
auto modules=QtLoadLibrary(saves.data(),collectQtplugs.size());
for(auto str:saves)delete str;
auto modules=QtLoadLibrarys(collectQtplugs);
if(modules.empty())return;
for(int i=0;i<collectQtplugs.size();i++){
OnNewSentenceS[collectQtplugs[i]]=GetProcAddress(modules[i],"OnNewSentence");
}