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下的常见动态库介绍

kernel32.dllMSDN: MSDN中关于kernel的介绍——The main module of the Windows CE operating system. The kernel p...
  • wutong_xingkong
  • wutong_xingkong
  • 2015年12月20日 21:13
  • 337

vb6.0创建“标准”DLL

vb6.0 IDE开发环境能创建 Activex DLL工程,这类工程发布的DLL,从严格意义上VB建立的DLL并不是像VC一样的动态链接库,VB建立的是ActiveX DLL,不能像kernel32...
  • xsjm206
  • xsjm206
  • 2012年02月26日 17:40
  • 2789

关于VB生成标准DLL文件

工程NewLinker.vbp模块文件NewLinker.basOption ExplicitPublic Sub Main()   Dim SpecialLink As Boolean, fCPL ...
  • adminlhb
  • adminlhb
  • 2006年09月19日 13:31
  • 3570

Windows平台上Caffe的训练与学习方法(以数据库CIFAR-10为例)

Windows平台上Caffe的训练与学习方法(以数据库CIFAR-10为例)         在完成winodws平台上的caffe环境的搭建之后,亟待掌握的就是如何在caffe中进行训练与学习...
  • FRD2009041510
  • FRD2009041510
  • 2016年12月03日 15:29
  • 748

标准dll的写法

有一些书是反反复复看过很多次,每次看都有点新体验。例如《com本质论》。晚上看了下,上面有些关于dll的论述,惭愧,才知道标准的dll(跨编译器并保持二进制布局一致)要怎么写,虽然之前写了n个com。...
  • linxiangyao
  • linxiangyao
  • 2010年02月03日 00:46
  • 1755

vs2008 C++创建和调用标准DLL

为了共享代码,需要生成标准的dll,本文将介绍在vs2008 C++生成及调用dll。 一、生成DLL     生成一个名为FunDll的dll文件,对外函数为addl。    step1:vs...
  • xsjm206
  • xsjm206
  • 2012年02月26日 21:18
  • 6939

VB编写标准DLL

发现一个神插件:vbadvance,可惜整整晚了十几年。VB本身只能编写COM(ActiveX DLL),而安装此插件后,即可编写标准的可以输出函数的DLL。无法是在自已的编程逻辑上还是工程分工上都有...
  • asanscape
  • asanscape
  • 2013年12月30日 22:22
  • 1063

在C#里如何调用标准DLL函数

在C#里只需要调用PInvoke (Platform Invocation) 服务。C# 支持一种sysimport属性支持这种调用。下面是完整的语法形式(在例子里没有用到所有的参数):[sysimp...
  • ghj1976
  • ghj1976
  • 2000年12月20日 22:14
  • 1732

windows下DLL的编写

      在VC中新建一个空的Win32动态链接库工程(Win32 Domanic-Link Library),然后添加一个C++ Sourse File到工程,我这里的文件名取DllTest.cp...
  • piaojun_pj
  • piaojun_pj
  • 2011年02月09日 21:09
  • 3945

介绍turtlebot的一个运行在Windows下的带GUI的APP

一、前言感谢博主Matthew的文章iRobot Create: Console App GUI Control 感谢iRobot Create项目组 我要介绍的这个软件是运行在Windows下的...
  • u013453604
  • u013453604
  • 2015年10月22日 21:03
  • 1265
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Windows平台下dll的标准内容
举报原因:
原因补充:

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