当前位置:网站首页>DLL bit by bit

DLL bit by bit

2022-06-13 06:03:00 You must know this and do it yourself

It is often used in the system DLL Program , Most of the DLL The program works at the bottom , Provide support for upper layer applications , Development DLL The following points shall be paid attention to during the procedure :
1、 Data storage and exchange
quite a lot DLL Programs are dynamically loaded ( use Loadlibrary function ),DLL The data in follows Freelibrary And died , Sometimes DLL The functions in are related , Such as DLL Middle function 2 need DLL Middle function 1 Generated data , At this point, the function is finished 1 when DLL already Freelibrary 了 , At another moment, the customer reloads DLL And call DLL The function in 2, That function 2 How to get the function 1 The generated data ? Whether to call the function again 1 Well ? left-off , You can use windows File mapping mechanism (IPC) To save the function 1 Generated data , Supply function 2 Use , The code is as follows :
Memory mapped files ( Shared memory ) Example :
// Write memory mapped file
extern "C" __declspec(dllexport)  void  __cdecl WriteMap(unsigned char* buff, int len=1024)
{
char MapName[16]={0};
HANDLE hMap;
LPVOID pBuffer;
sprintf(MapName,"%s","ShareMemory");        
hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, MapName);
if (hMap==NULL){
hMap = CreateFileMapping(INVALID_HANDLE_VALUE,
                                    NULL,
                                    PAGE_READWRITE,
                                    0,
                                    len+1,
                                    MapName);
}
        pBuffer = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
        memcpy(pBuffer,buff,len);
}

// Read memory mapped file
extern "C" __declspec(dllexport) int __cdecl  ReadMap(unsigned char* buff,int len=1024)

{
char MapName[16]={0};
HANDLE hMap;
LPVOID pBuffer;
sprintf(MapName,"%s","ShareMemory");
hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, MapName);
if (hMap==NULL){
return -1;
}
pBuffer = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
memcpy(buff,pBuffer,len);
UnmapViewOfFile(pBuffer);
CloseHandle(hMap);
return 0;
}
WriteMap The function is responsible for DLL Middle function 1 Write the data to the memory mapped file ,ReadMap The function is responsible for reading the written data , Once the data is written , As long as the client's program is running , No matter DLL Released or loaded , Data always exists ( The memory mapped file in this example is equivalent to shared memory )
2、 Reentry prevention and queuing
quite a lot DLL It is time-consuming communication or equipment IO operation , To be on the safe side DLL Functions in should prevent threads from re entering , Or queue up , Ensure correct operation , You can use techniques such as semaphores or critical areas to protect your code .
3、 routing problem
Sometimes it needs to be in DLL In order to get DLL Path to file , At this time, we can obtain (win32 DLL nothing MFC Support )
First get and save DLL Handle
HMODULE m_hModule;  // Definition m_hModule, preservation DLL Handle    
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
 )
{
    m_hModule=hModule;  // preservation DLL Handle
    return TRUE;
}

And then use getDLLPath Function is used to obtain DLL route :
void getDLLPath(HANDLE hModule, char* DLLPath) {
char DLLPathTemp[1024] = { 0 };
GetModuleFileName((HMODULE)hModule, DLLPathTemp, 1024);
strncpy(
DLLPath, DLLPathTemp, strrchr(DLLPathTemp, '\\') - DLLPathTemp + 1);  // Take out the path of the file
}

The advantage of this is that no matter DLL What's the name , Can dynamically obtain DLL The path of .
If you generate DLL When used MFC, You can use the following methods to obtain DLL The path of , Here's a snippet of the program
// The only one CMemoryMapDllApp object
CMemoryMapDllApp theApp;
// CMemoryMapDllApp initialization
BOOL CMemoryMapDllApp::InitInstance()
{
CWinApp::InitInstance();
char disp[128]={0};
char DLLPathTemp[1024] = { 0 };
sprintf(disp,"%s.dll",theApp.m_pszAppName);
GetModuleFileName(GetModuleHandle(disp), DLLPathTemp, 1024);  //DLLPathTemp It's preserved in DLL The path of
//MessageBox(NULL,DLLPathTemp,"dll path",0);
return TRUE;
}
4、 File permissions
Sometimes our DLL The program shall be installed in the embedded system wince or xp And other embedded terminal devices , These systems set read and write permissions on certain directories , That's when our DLL You should pay attention to the file operation , In order to prevent the operation error from causing the program to crash .
5、 Export functions and _cdecl _stdcall
_stdcall yes Pascal The default calling mode of the program , The parameters are stack pressed from right to left , The called function itself clears the stack before returning .WIN32 Api All use _stdcall Call mode ._cdecl yes C/C++ Default calling method , The parameters are stack pressed from right to left , The memory stack that passes parameters is maintained by the caller ._cedcl The agreed function can only be C/C++ call , Every function that calls it contains the code to empty the stack , So the size of the resulting executable is larger than that of the call _stdcall The size of the function . If our function uses _cdecl, Then the stack is cleared by the caller , This brings about a problem , Different compilers produce stacks in different ways , Can the caller complete the cleanup work normally ? The answer is no . If you use __stdcall, The above problems are solved , The function solves the cleanup by itself . therefore , across ( Development ) The platform is being called , We all use __stdcall( Although sometimes with WINAPI The appearance of ). So why do we need _cdecl Well ? When we encounter such a function as fprintf() Its parameters are variable , Indefinitely long , The callee cannot know the length of the parameter in advance , The cleaning work after the event can not be carried out normally , therefore , In this case we can only use _cdecl.  Here we have a conclusion , If your program does not involve variable parameters , Best use __stdcall.6、 Link issues
DLL When compiling the program, try to chain all dependent libraries into the program at one time , In especial MFC Of DLL Pay attention to the compile time selection “ Use... In a static library MFC”, lest DLL Possible errors on different devices after release .
7、Dll pack
Sometimes we are DLL Another... Is dynamically loaded in DLL, At this time, you can consider adding another DLL Packaged as a resource into our DLL in , Dynamically release when using DLL, The code is as follows :
HMODULE hThis = hModuleDll;  //DLL Handle
HRSRC   hRes = FindResource(hThis, MAKEINTRESOURCE(IDR_DLL1), "DLL");
HGLOBAL hGres = LoadResource(hThis, hRes);
HANDLE  hFile = CreateFile("TesoLive.dll", GENERIC_WRITE, NULL, NULL, CREATE_NEW,FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, NULL);
PVOID   pRes = LockResource(hGres);
DWORD   dwSize = SizeofResource(hThis, hRes);
DWORD dwSizeWritten = 0;
WriteFile(hFile, pRes, dwSize, &dwSizeWritten,
NULL);
CloseHandle(hFile);
Now you can load “
TesoLive.dll 了 .
8、DLL Development tool selection
If our DLL Need to be used in java or python Wait for the environment , Do not choose a version that is too high vs, Such as vs2105 In the environment DLL stay jdk1.6 or python2 There is a compatibility problem on , Now many enterprise applications are still in jdk1.6 or python2 On such a platform , So now we are developing DLL Use vs2005 It's more appropriate , do DLL Not too far ahead .

原网站

版权声明
本文为[You must know this and do it yourself]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202270558178320.html