溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何淺析C++動(dòng)態(tài)加載DLL在Windows Mobile下實(shí)現(xiàn)

發(fā)布時(shí)間:2021-11-24 09:34:57 來(lái)源:億速云 閱讀:341 作者:柒染 欄目:編程語(yǔ)言

如何淺析C++動(dòng)態(tài)加載DLL在Windows Mobile下實(shí)現(xiàn),很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

靜態(tài)加載DLL的方法

使用Native C++的開(kāi)發(fā),一般使用靜態(tài)加載的方法加載DLL,所謂靜態(tài)加載就是在程序編譯時(shí)(Compile Time)直接調(diào)用DLL的頭文件定義的函數(shù),鏈接時(shí)(Link Time)鏈接*.lib文件指向DLL的接口,在程序開(kāi)始運(yùn)行時(shí)(Run Time Start up)加載DLL。

下面講述使用靜態(tài)加載DLL的方法,在程序中需要指定加載的*.lib文件,用于鏈接(Link)。

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

使用靜態(tài)加載的DLL可以直接調(diào)用頭文件定義的函數(shù),例如:

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

SmiAccelerometerGetCapabilities()和SmiAccelerometerRegisterHandler()是定義在頭文件smiAccelerometer.h中的,可以直接調(diào)用,定義如下:

使用靜態(tài)加載的方法使用方面還是很方便的,可是在動(dòng)態(tài)加載的時(shí)候就不能直接調(diào)用頭文件的函數(shù)了,增加了復(fù)雜度,下面會(huì)講到。

/**  *  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 handler);

C++動(dòng)態(tài)加載DLL的方法

靜態(tài)加載DLL是比較簡(jiǎn)單的開(kāi)發(fā)方法,可是有個(gè)缺點(diǎn)是程序開(kāi)始運(yùn)行的時(shí)候就需要加載DLL,如果該DLL不存在,程序就不能啟動(dòng)了。由于Windows Mobile Sensors API庫(kù)需要自適應(yīng)具體的設(shè)備,也就是說(shuō)Windows Mobile Sensors API庫(kù)不能依賴于具體設(shè)備的Sensor庫(kù),所以不能使用靜態(tài)加載的方法來(lái)引用DLL。下面講述動(dòng)態(tài)加載DLL的方法。

定義指向函數(shù)的指針

動(dòng)態(tài)加載DLL,需要根據(jù)頭文件來(lái)定義指向函數(shù)的指針,如下:

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;

這些指向函數(shù)的指針可以對(duì)應(yīng)下面的在smiAccelerometer.h頭文件的函數(shù)進(jìn)行定義:

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();

定義是一一對(duì)應(yīng)的。參數(shù)入口和返回值都必須完全一致。

初始化指向函數(shù)的指針

初始化指向函數(shù)的指針的過(guò)程也就是動(dòng)態(tài)加載DLL的過(guò)程,代碼如下:

#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()函數(shù)動(dòng)態(tài)加載DLL,GetProcAddress()根據(jù)函數(shù)的名字 加載函數(shù)的入口地址 到指向函數(shù)的指針。有點(diǎn)繞口,sorry。如果地址不為空,那么可以根據(jù)這個(gè)地址調(diào)用相應(yīng)的函數(shù)。

調(diào)用函數(shù)

調(diào)用函數(shù)的方法和靜態(tài)加載DLL的方法一樣,但是不是直接調(diào)用函數(shù)的名字,而是使用指向函數(shù)的指針來(lái)調(diào)用,下面的例子可以和靜態(tài)加載DLL函數(shù)調(diào)用的例子對(duì)比來(lái)看。

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

C++動(dòng)態(tài)加載DLL的方法就完成了。

.NET的世界

下面這段表述不對(duì),請(qǐng)看下面的回復(fù)。.NET使用DllImport屬性進(jìn)行P/Invoke不應(yīng)該叫做動(dòng)態(tài)加載,因?yàn)椴荒苄遁d,應(yīng)該叫做按需加載,就是在call這個(gè)函數(shù)的時(shí)候才加載,而不是在程序啟動(dòng)的時(shí)候加載。按需加載和靜態(tài)加載的區(qū)別是加載的時(shí)間不一樣。

{

在.NET里面P/Invoke一個(gè)DLL里面的函數(shù)全部都是動(dòng)態(tài)加載(這是錯(cuò)的,謝謝Wuya指出,這里應(yīng)該叫做按需加載,動(dòng)態(tài)加載的方法可以見(jiàn)Wuya到回復(fù))的,使用DllImport屬性來(lái)定義。如果SmiAccelerometerUnregisterHandler()函數(shù)使用在.NET下會(huì)定義如下:

[DllImport("SamsungMobileSDK_1.dll", CharSet = CharSet.Auto, SetLastError = true)]private static extern uint SmiAccelerometerUnregisterHandler();使用.NET比使用Native C++動(dòng)態(tài)加載相對(duì)簡(jiǎn)單。

}

關(guān)于Mobile Sensors API項(xiàng)目

這個(gè)項(xiàng)目還是在起步階段,當(dāng)前實(shí)現(xiàn)了samsung的重力感應(yīng)器,我把項(xiàng)目host到 Mobile Sensors API - Native unified APIs for Windows Mobile Sensors 了,我會(huì)持續(xù)改進(jìn),把各種sensors的實(shí)現(xiàn)到這個(gè)項(xiàng)目中。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI