Windows平台下dll的标准内容

原创 2007年09月15日 16:47:00
   在Windows平台上编写dll的时候.一个dll应该要包括下面的方法。
1.DllMain方法
   DllMain方法和可执行程序的WinMain类似,是dll的入口函数。在dll装载和卸载等时候,都会被调用。这样dll的作者就有机会处理初始化和清理资源。下面是一个DllMain的样例代码:
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
    
switch (ul_reason_for_call)
    
{
        
case DLL_PROCESS_ATTACH: 
            g_module 
= hModule; 

            
break;

        
case DLL_THREAD_ATTACH:
        
case DLL_THREAD_DETACH:
        
case DLL_PROCESS_DETACH:
            
break;
    }

    
return TRUE;
}

2.在引用dll的时候必须要将dll拷贝到可执行程序所在的目录下面。为了让其他地方的代码也可以调用该dll。就必须在操作系统中注册这个dll.和注册有关的方法有两个。下面是样例代码:
STDAPI DllRegisterServer(void)
{
    
// 这个类应该创建标准的注册表入口 
    CDllRegistrar registrar; 
    
char path [ MAX_PATH ];
    GetModuleFileName((HMODULE)g_module,path,MAX_PATH);
    
return registrar.RegisterObject(CLSID_Mine,"MineLib","MathObj",path) ? S_OK:S_FALSE;
}


STDAPI DllUnregisterServer(
void)
{
    CDllRegistrar registrar;
    
return registrar.UnRegisterObject(CLSID_Mine,"MineLib","MathObj"? S_OK:S_FALSE;
}
注册用到了CDllRegistrar类,这是一个Helper类。代码如下:

#if !defined(_REGISTRAR_H)
#define _REGISTRAR_H

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include 
"stdio.h"

class CRegistrar
{
protected:
    CRegistrar() 
{};

    BOOL SetInRegistry(HKEY hRootKey, LPCSTR subKey, LPCSTR keyName,LPCSTR keyValue)
    
{
        HKEY hKeyResult;
        DWORD dataLength;
        DWORD dwDisposition;
        
if (RegCreateKeyEx( hRootKey, subKey, 0, NULL, REG_OPTION_NON_VOLATILE, 
                            KEY_WRITE, NULL, 
&hKeyResult, &dwDisposition) != ERROR_SUCCESS)
        
{
            
return FALSE;
        }

        dataLength 
= strlen(keyValue);
        DWORD retVal 
= RegSetValueEx( hKeyResult, keyName, 0, REG_SZ,(const BYTE *) keyValue, dataLength);
        RegCloseKey(hKeyResult);
        
return (retVal == ERROR_SUCCESS) ? TRUE:FALSE;
    }


    BOOL DelFromRegistry(HKEY hRootKey, LPCTSTR subKey)
    
{
        
long retCode;
        retCode 
= RegDeleteKey(hRootKey, subKey);
        
if (retCode != ERROR_SUCCESS)
            
return false;
        
return true;
    }


    
bool StrFromCLSID(REFIID riid,LPSTR strCLSID)
    
{
        LPOLESTR pOleStr 
= NULL;
        HRESULT hr 
= ::StringFromCLSID(riid,&pOleStr);
        
if(FAILED(hr))
            
return false;
        
int bytesConv = ::WideCharToMultiByte(CP_ACP,0,pOleStr,wcslen(pOleStr),strCLSID,MAX_PATH,NULL,NULL);
        CoTaskMemFree(pOleStr);
        strCLSID [ bytesConv ] 
= '';
        
if(!bytesConv)
        
{
            
return false;
        }

        
return true;
    }

public:
    
bool RegisterObject(REFIID riid,LPCSTR LibId,LPCSTR ClassId)
    
{
        
char strCLSID [ MAX_PATH ];
        
char Buffer [ MAX_PATH ];
        
        
if(!strlen(ClassId))
            
return false;

        
if(!StrFromCLSID(riid,strCLSID))
            
return false;
        
        
if(!strlen(LibId) && strlen(ClassId))
            sprintf(Buffer,
"%s.%s/CLSID",ClassId,ClassId);
        
else
            sprintf(Buffer,
"%s.%s/CLSID",LibId,ClassId);

        BOOL result;
        result 
= SetInRegistry(HKEY_CLASSES_ROOT,Buffer,"",strCLSID);
        
if(!result)
            
return false;
        sprintf(Buffer,
"CLSID/%s",strCLSID);
        
char Class [ MAX_PATH ];
        sprintf(Class,
"%s Class",ClassId);
        
if(!SetInRegistry(HKEY_CLASSES_ROOT,Buffer,"",Class))
            
return false;
        sprintf(Class,
"%s.%s",LibId,ClassId);
        strcat(Buffer,
"/ProgId");

        
return SetInRegistry(HKEY_CLASSES_ROOT,Buffer,"",Class) ? true:false;
    }


    
bool UnRegisterObject(REFIID riid,LPCSTR LibId,LPCSTR ClassId)
    
{
        
char strCLSID [ MAX_PATH ];
        
char Buffer [ MAX_PATH ];
        
if(!StrFromCLSID(riid,strCLSID))
            
return false;
        sprintf(Buffer,
"%s.%s/CLSID",LibId,ClassId);
        
if(!DelFromRegistry(HKEY_CLASSES_ROOT,Buffer))
            
return false;
        sprintf(Buffer,
"%s.%s",LibId,ClassId);
        
if(!DelFromRegistry(HKEY_CLASSES_ROOT,Buffer))
            
return false;
        sprintf(Buffer,
"CLSID/%s/ProgId",strCLSID);
        
if(!DelFromRegistry(HKEY_CLASSES_ROOT,Buffer))
            
return false;
        sprintf(Buffer,
"CLSID/%s",strCLSID);
        
return DelFromRegistry(HKEY_CLASSES_ROOT,Buffer) ? true:false;
    }

}
;

class CDllRegistrar : public CRegistrar
{
public:
    
bool RegisterObject(REFIID riid,LPCSTR LibId,LPCSTR ClassId,LPCSTR Path)
    
{
        
if(! CRegistrar::RegisterObject(riid,LibId,ClassId))
            
return false;

        
char strCLSID [ MAX_PATH ];
        
char Buffer [ MAX_PATH ];
        
if(!StrFromCLSID(riid,strCLSID))
            
return false;
        sprintf(Buffer,
"CLSID/%s/InProcServer32",strCLSID);
        
return SetInRegistry(HKEY_CLASSES_ROOT,Buffer,"",Path) ? true:false;
    }


    
bool UnRegisterObject(REFIID riid,LPCSTR LibId,LPCSTR ClassId)
    
{
        
char strCLSID [ MAX_PATH ];
        
char Buffer [ MAX_PATH ];
        
if(!StrFromCLSID(riid,strCLSID))
            
return false;
        sprintf(Buffer,
"CLSID/%s/InProcServer32",strCLSID);
        
if(!DelFromRegistry(HKEY_CLASSES_ROOT,Buffer))
            
return false;
        
return CRegistrar::UnRegisterObject(riid,LibId,ClassId);
    }


}
;

#endif

相关文章推荐

Windows平台下动态链接库DLL的总结

1、 动态链接库与静态连接库        静态连接库与动态链接库都是经过编译器编译之后的,在计算机上可以直接运行的二进制目标文件,就像exe文件一样,但不同于exe文件的是静态链接库和动态链接...

unity防反编译 windows平台加密dll

功能取决于需求,在实现这功能之前,却有一个小小的插曲,有同学认为,并不需要去实现游戏加密,再怎样也会被破解,何必浪费精力。虽然这样说,但是我们所做的加密至少也会增加一点破解成本,不会让我们辛苦写的代码...

Windows平台下erlang的port进程关闭标准输入输出的方法

转载:http://arksea.iteye.com/blog/700032   为了避免与port进程的通信受一些printf调试信息的影响,通常都要关闭或者替换标准输入输出。  Un...

odoo在Windows平台下部署无内容显示问题

odoo在Windows平台下部署无内容显示问题问题描述:在Windows下部署oddo10在数据库建立后仅显示背景与logo解决方法:文件名:mimetypes.py def read_win...

Nginx在Windows平台的配置

  • 2017年11月01日 20:25
  • 332KB
  • 下载

windows平台HTTP代理服务器搭建(CCproxy)

windows平台HTTP代理服务器搭建(CCproxy)

windows平台下基于UDP的socket编程

  • 2015年07月01日 17:12
  • 2KB
  • 下载

定时器 VER4.0 (Windows平台)

  • 2013年09月02日 00:32
  • 489KB
  • 下载

windows平台下 wampserver(php集成环境)修改Mysql密码的问题及wampserver更改默认web根目录

一wampserver修改Mysql密码的问题: 解决方法:  WAMP安装好后,mysql密码是为空的,那么要如何修改呢?其实很简单,通过几条指令就行了,下面我就 一步步来操作。     ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Windows平台下dll的标准内容
举报原因:
原因补充:

(最多只允许输入30个字)