2014-09-22 23 views
0

我遇到以下問題。無法讀取由CoTaskMemAlloc分配的結構的內存

我正在實現一個IDataObject,它負責將文件傳遞到剪貼板。當我在我的IDataObject上調用GetData時,它似乎會返回一個空的STGMEDIUM結構,其中包含無法讀取的內存,雖然我可以通過斷點確認結構是否填充了正確的值。這是我的代碼:

電話的GetData:

FORMATETC dsl_form={//some FORMATETC}; 
STGMEDIUM *dsl_med = {0}; 

HRESULT hr; 
hr=dsp_in->GetData(&dsl_form, dsl_med); 

的的GetData-功能:

HRESULT STDMETHODCALLTYPE GetData(FORMATETC *dsp_fmt,STGMEDIUM *dsp_med) { 
    int iml_idx=m_lookup_format(dsp_fmt);//Search the FORMATETC-Array for a Format that equals the given Format 
    //If no suitable FormatEtc was found, report an error 
    if(iml_idx<0){ 
     return DV_E_FORMATETC; 
    } 
    //Allocate and fill a new STGMEDIUM structure 
    dsp_med=(STGMEDIUM*) CoTaskMemAlloc(sizeof STGMEDIUM); 
    dsp_med->tymed=dsc_filedesc[iml_idx].tymed; 
    dsp_med->pUnkForRelease=0; 
    switch(dsc_filedesc[iml_idx].tymed) { 
    case TYMED_HGLOBAL:  dsp_med->hGlobal=m_dup_global_mem(dsc_filecontents[iml_idx].hGlobal); 
          break; 
    default:    return DV_E_FORMATETC; 
    } 

    return S_OK; 

回答

0

STGMEDIUM *dsl_med = {0}; 

HRESULT hr; 
hr=dsp_in->GetData(&dsl_form, dsl_med); 

副本空dsl_med到函數參數,調用的函數更改傳遞給它的副本,但原始的null值保持不變,因此指針在calle上r方保持爲空。

一個選項是更改函數簽名,以便它接受STGMEDIUM**並相應地更改其餘代碼。但在這種情況下 - 執行IDataObject::GetData()時,您無法更改簽名。如果你閱讀MSDN描述,它將解釋函數應該只分配它分配給結構成員的東西,而調用者必須分配結構並有選擇地釋放它的成員。

所以,你必須要通過結構

STGMEDIUM dsl_med = {0}; 
object->GetData(&dsl_from, &dsl_med); 

的地址和函數內部,你剛纔設置的結構成員。

+0

可悲的是這是不可能的,因爲我要堅持接口IDataObject的其中規定,就是必須是這樣的:HRESULT的GetData( [中] FORMATETC * pformatetcIn, [出] STGMEDIUM * P中 ); – BenMorgan 2014-09-22 10:51:19

+0

據我瞭解C++,我交給GetData-Method指針的副本,指針的目標應該仍然是相同的,不應該嗎? – BenMorgan 2014-09-22 10:52:37

+0

是的,但是您試圖更改在函數內傳遞的值,並且該更改不會傳回。您傳遞的是空指針,null將更改爲非null,但調用者只會看到原始的null。 – sharptooth 2014-09-22 10:54:22