Chinaunix首页 | 论坛 | 博客
  • 博客访问: 183932
  • 博文数量: 20
  • 博客积分: 1847
  • 博客等级: 上尉
  • 技术积分: 245
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-02 23:39
文章分类

全部博文(20)

文章存档

2012年(3)

2011年(11)

2010年(6)

我的朋友

分类: C/C++

2011-01-23 18:54:54

静态加载DLL的方法
     使用Native C++的开发,一般使用静态加载的方法加载DLL,所谓静态加载就是在程序编译时(Compile Time)直接调用DLL的头文件定义的函数,链接时(Link Time)链接*.lib文件指向DLL的接口,在程序开始运行时(Run Time Start up)加载DLL。

  下面讲述使用静态加载DLL的方法,在程序中需要指定加载的*.lib文件,用于链接(Link)。

    #pragma comment(lib, "SamsungMobileSDK_1.lib")

使用静态加载的DLL可以直接调用头文件定义的函数,例如:

    SmiAccelerometerCapabilities cap; 
if( SmiAccelerometerGetCapabilities(&cap) != SMI_SUCCESS){    throw;} 
SmiAccelerometerHandler h = &GetVectorHandler;if(SmiAccelerometerRegisterHandler(1000, h) != SMI_SUCCESS) 
{    throw;} 

SmiAccelerometerGetCapabilities()和SmiAccelerometerRegisterHandler()是定义在头文件smiAccelerometer.h中的,可以直接调用,定义如下:

使用静态加载的方法使用方面还是很方便的,可是在动态加载的时候就不能直接调用头文件的函数了,增加了复杂度,下面会讲到。


/**   
*  Start receiving accelerometer data periodically.    
*    
*  The period interval must be a multiple of the callbackPeriod specified    
*  in SmiAccelerometerCapabilities. If it is less than the callbackPeriod, it will be    
*  set to the callbackPeriod. If it is not a multiple of the callbackPeriod, it will be    
*  truncated to fit the value. ( (period / callbackPeriod)    
* callbackPeriod )    
*      
*  Only one handler per process is allowed. Successive calls per process will replace the previous handler    
*  function and period.    
*   
*  @param    period    [in]    callback interval.       
*  @param    handler   [in]    callback function for every period interval.      
*    
*  @return                       
*                              SMI_SUCCESS on success    
*  \n                          SMI_ERROR_INVALID_PARAMETER if the handler input parameter is NULL    
*  \n                          SMI_ERROR_DEVICE_NOT_FOUND if the device is not present or supported    
*  \n                          SMI_ERROR_CANNOT_ACTIVATE_SERVER if the sensor server cannot be started    
*/ SMI_API SMI_RESULT SmiAccelerometerRegisterHandler(UINT period, SmiAccelerometerHandler 

C++动态加载DLL的方法

  静态加载DLL是比较简单的开发方法,可是有个缺点是程序开始运行的时候就需要加载DLL,如果该DLL不存在,程序就不能启动了。由于Windows Mobile Sensors API库需要自适应具体的设备,也就是说Windows Mobile Sensors API库不能依赖于具体设备的Sensor库,所以不能使用静态加载的方法来引用DLL。下面讲述动态加载DLL的方法。

定义指向函数的指针

  动态加载DLL,需要根据头文件来定义指向函数的指针,如下:

typedef UINT (WINAPI * PFN_SmiAccelerometerGetVector)(SmiAccelerometerVector*);    
typedef UINT (WINAPI * PFN_SmiAccelerometerGetCapabilities)(SmiAccelerometerCapabilities*);    
typedef UINT (WINAPI * PFN_SmiAccelerometerRegisterHandler)(UINT, SmiAccelerometerHandler);typedef UINT (WINAPI * PFN_SmiAccelerometerUnregisterHandler)();    
PFN_SmiAccelerometerGetVector pfnSmiAccelerometerGetVector;PFN_SmiAccelerometerGetCapabilities     
pfnSmiAccelerometerGetCapabilities;PFN_SmiAccelerometerRegisterHandler     
pfnSmiAccelerometerRegisterHandler;PFN_SmiAccelerometerUnregisterHandler pfnSmiAccelerometerUnregisterHandler

这些指向函数的指针可以对应下面的在smiAccelerometer.h头文件的函数进行定义:


SMI_API SMI_RESULT SmiAccelerometerGetVector(SmiAccelerometerVector *accel);   
SMI_API SMI_RESULT SmiAccelerometerGetCapabilities(SmiAccelerometerCapabilities *capabilities);   
SMI_API SMI_RESULT SmiAccelerometerRegisterHandler(UINT period, SmiAccelerometerHandler handler);   
SMI_API SMI_RESULT SmiAccelerometerUnregisterHandler();

定义是一一对应的。参数入口和返回值都必须完全一致。

  初始化指向函数的指针

  初始化指向函数的指针的过程也就是动态加载DLL的过程,代码如下:


  • #define SAMSUNG_SENSOR_DLL  
  • L"SamsungMobilesdk_1.dll"HMODULE hSensorLib = LoadLibrary (SAMSUNG_SENSOR_DLL);if (NULL == hSensorLib){      
  • printf("Unable to load Samsung Sensor DLL\n");      
  • throw std::runtime_error("Unable to load Samsung Sensor DLL");}  
  • pfnSmiAccelerometerGetVector = (PFN_SmiAccelerometerGetVector)      
  • GetProcAddress(hSensorLib, L"SmiAccelerometerGetVector");pfnSmiAccelerometerGetCapabilities = (PFN_SmiAccelerometerGetCapabilities)      
  • GetProcAddress(hSensorLib, L"SmiAccelerometerGetCapabilities");pfnSmiAccelerometerRegisterHandler = (PFN_SmiAccelerometerRegisterHandler)      
  • GetProcAddress(hSensorLib, L"SmiAccelerometerRegisterHandler");pfnSmiAccelerometerUnregisterHandler = (PFN_SmiAccelerometerUnregisterHandler)     
  • GetProcAddress(hSensorLib, L"SmiAccelerometerUnregisterHandler");if (NULL == pfnSmiAccelerometerGetVector){    printf("Unable to find entry point of SmiAccelerometerGetVector\n");      
  • throw std::runtime_error("Unable to find entry point of SmiAccelerometerGetVector");}if (NULL == pfnSmiAccelerometerGetCapabilities){      
  • printf("Unable to find entry point of SmiAccelerometerGetCapabilities\n");      
  • throw std::runtime_error("Unable to find entry point of SmiAccelerometerGetCapabilities");}if (NULL == pfnSmiAccelerometerRegisterHandler){      
  • printf("Unable to find entry point of SmiAccelerometerRegisterHandler\n");      
  • throw std::runtime_error("Unable to find entry point of SmiAccelerometerRegisterHandler");}if (NULL == pfnSmiAccelerometerUnregisterHandler){      
  • printf("Unable to find entry point of SmiAccelerometerUnregisterHandler\n");      
  • throw std::runtime_error("Unable to find entry point of SmiAccelerometerUnregisterHandler
  • LoadLibrary()函数动态加载DLL,GetProcAddress()根据函数的名字 加载函数的入口地址 到指向函数的指针。有点绕口,sorry。如果地址不为空,那么可以根据这个地址调用相应的函数。

      调用函数

      调用函数的方法和静态加载DLL的方法一样,但是不是直接调用函数的名字,而是使用指向函数的指针来调用,下面的例子可以和静态加载DLL函数调用的例子对比来看。


    SmiAccelerometerCapabilities cap;    
    if( pfnSmiAccelerometerGetCapabilities(&cap) != SMI_SUCCESS)   
     {       
    throw;}SmiAccelerometerHandler h = &GetVectorHandler;   
    if(pfnSmiAccelerometerRegisterHandler(1000, h) != SMI_SUCCESS)   
    {    throw;} 

       C++动态加载DLL的方法就完成了。

     

    阅读(5998) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~