2017-02-12 3 views
0

У меня проблема, и я буду очень признателен, если вы поможете мне.CString, использующийся для статического метода

У меня есть MDI, и в классе CDocument, у меня есть:-структуру

CMyDoc.h

class CMyDoc : public CDocument 
{ 
... 

struct SRecord 
{ 
    SRecord(){} 
    virtual ~SRecord(){} 
    CString sName; 
    CString sState; 
    CString sDateu; 
    CString sDatec; 
}; 

CTypedPtrArray<CPtrArray, SRecord*> m_arrRecord; 

и где-то я загрузить эту структуру с данными:

SRecord* pItem = new SRecord; 
    pItem->sName  = saItem.GetAt(ML_ASSETNAME); 
    pItem->sState  = saItem.GetAt(ML_STATE); 
    pItem->sDateu  = saItem.GetAt(ML_DATEU; 
    pItem->sDatec  = saItem.GetAt(ML_DATEC); 
    m_arrRecord.Add(pItem); 

ОК , Я пытаюсь сортировать данные:

void CMyDoc::SortData(int nColumn, BOOL bAscending) 
{ 
switch(nColumn) 
{ 
case 9: 
    if(bAscending)qsort((void*)m_arrRecord.GetData(), m_arrRecord.GetSize(), sizeof(SRecord), CompareDateUAscending); 
    else qsort((void*)m_arrRecord.GetData(), m_arrRecord.GetSize(), sizeof(SRecord), CompareDateUDescending); 
    break; 
... 
} 

но проблема стать, когда данные доступа в статическом методе:

int CMyDoc::CompareDateUDescending(const void* arg1, const void* arg2) 
{ 
SRecord* Record1 = (SRecord*)arg1; 
SRecord* Record2 = (SRecord*)arg2; 

if(Record1->sDateu.IsEmpty() || Record2->sDateu.IsEmpty()) // <--- crash ! 
    return 0; 

COleDateTime dL, dR; 
dL.ParseDateTime(Record1->sDateu); 
dR.ParseDateTime(Record2->sDateu); 

return (dL == dR ? 0 : (dL < dR ? 1 : -1)); 
} 

и аварии принимают меня здесь (atlsimpstr.h):

CStringData* GetData() const throw() 
{ 
    return(reinterpret_cast< CStringData* >(m_pszData)-1); // the crash lead me on this line 
} 

что я делаю неправильно?

Любая помощь будет очень признательна!

Update:

Я попытался это:

int CMyDoc::CompareDateUDescending(const void* arg1, const void* arg2) 
{ 
SRecord* Record1 = *(SRecord**)arg1; // <-- OK 
SRecord* Record2 = *(SRecord**)arg2; // <-- Unhandled exception* see note below 

if(Record1->sDateu.IsEmpty() || Record2->sDateu.IsEmpty()) 
    return 0; 

COleDateTime dL, dR; 
dL.ParseDateTime(Record1->sDateu); 
dR.ParseDateTime(Record2->sDateu); 

return (dL == dR ? 0 : (dL < dR ? 1 : -1)); 
} 

и крах сказал мне:

"Необработанное исключение встречается во время обратного вызова пользователя" странно ...

+1

Вопросы, требующие помощи по отладке, должны содержать [mcve] вместе с сообщением об ошибке.Вы также должны описать, что должен делать код и каким образом он этого не делает. Atm неясно, в чем проблема – user463035818

+0

Хорошо, я пытаюсь уточнить. – flaviu2

+0

Одна проблема: 'sizeof (SRecord)' должен быть 'sizeof (SRecord *)' – franji1

ответ

1

Функция сравнения qsort получает указатели к элементам в массиве. Но так как элементы в массиве сами являются указателями, то, что ваша конкретная функция получает в качестве аргументов, являются указателями на указатели на SRecord, то есть SRecord**.

Вы можете решить это, выполнив, например,

const SRecord* Record1 = *reinterpret_cast<const SRecord**>(arg1); 

То есть, вы приводите arg1 к SRecord** и затем разыменованию этого указателя, чтобы получить SRecord*.


Пример использования C++ standard sort function.

Прежде всего, необходимо обновить функцию сравнения немного:

// The comparison function should return true if Record1 is *smaller* than Record2, 
// and return false otherwise 
bool CMyDoc::CompareDateUDescending(const SRecord* Record1, const SRecord* Record2) 
{ 
    return Record1->sDateu < Record2->sDateu; 
} 

Тогда для вызова сортировать:

std::sort(m_arrRecord.GetData(), m_arrRecord.GetData() + m_arrRecord.GetSize(), CompareDateUDescending); 

Много проще!

+1

Я пробовал ваш код, но я получаю следующее: ошибка C2440: 'reinterpret_cast': не может преобразовать из 'const void *' в 'CMyDoc :: SRecord **' ... Я чувствую, что я не за горами, чтобы решить эту проблему. .. – flaviu2

+0

@ flaviu2 Ах, пропустили бит 'const'. Добавил их в свой ответ. Я думаю ... Что-то в этом роде. :) –

+0

Хм ... после того, как я поставил то, что вы сказали, я получаю довольно ту же ошибку: ошибка C2440: 'reinterpret_cast': не может преобразовать из 'const void *' в 'const CMyDoc :: SRecord **' ... странно. .. – flaviu2