ReadFile from COMponent
От: sndralex Израиль www.gdetotam.co.il
Дата: 20.03.02 15:05
Оценка:
Uvazhaemie Gospoda!
Pomogite razobrat'sya s problemoi:
Ya sozdau s pomosh'u ATL elementarnij COMponent s dvumya funkciyami:

[id(1), helpstring("method ReadFromFile")] HRESULT ReadFromFile([in] BSTR fName, [out, retval] BSTR *txtRet);
[id(2), helpstring("method Save2File")] HRESULT Save2File([in] BSTR fName, [in] BSTR txt2save);

V funkcii ReadFromFile ya prosto chitau text iz faila i vozvrashau ego.
I poluchau — error : Memory couldn't be 'written'
hotya tot zhe kod v obichnoi programme (ne v COM) rabotaet bezukoriznenno, edinstvennoe otlichie preobrazovanie iz char* v BSTR.

Esli uvazhaemie specialisti smogut vzglyanut' na privedennii nizhe code i ukazat' mne na oshibku budu priznatelen :-).



STDMETHODIMP CFIO::ReadFromFile(BSTR fName, BSTR *txtRet)
{
    // TODO: Add your implementation code here
    USES_CONVERSION;
    _bstr_t bstrFName(fName,FALSE);
    HANDLE hFile;
    DWORD dwFileSize;
    DWORD dwBytesRead;
    BOOL bResult;
    char *pBuf;

    hFile = CreateFile(bstrFName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) 
    {
        CloseHandle(hFile);
        return E_FAIL;
    }
    dwFileSize = GetFileSize(hFile,NULL);
    dwBytesRead = 0;
    if (dwFileSize == INVALID_FILE_SIZE)
    {
        CloseHandle(hFile); 
        return E_FAIL;
    } 
    pBuf = new char[dwFileSize];
    bResult = ReadFile(hFile,pBuf,dwFileSize,&dwBytesRead,NULL);
    if (bResult==0)
    {
        CloseHandle(hFile); 
        return E_FAIL;
    } 

    *txtRet = ::SysAllocString(A2OLE(pBuf));
//    delete pBuf;
    CloseHandle(hFile); 
    return S_OK;
}


P.S.
proshu prosheniya za translit, poka u menya net drugoi vozmozhnosti beglo pisat' po russki
Alexander N. Treyner
Re: ReadFile from COMponent
От: OlegO Россия http://www.mediachase.ru
Дата: 20.03.02 15:20
Оценка:
Здравствуйте sndralex, Вы писали:

S>Uvazhaemie Gospoda!

S>Pomogite razobrat'sya s problemoi:
S>Ya sozdau s pomosh'u ATL elementarnij COMponent s dvumya funkciyami:

S>[id(1), helpstring("method ReadFromFile")] HRESULT ReadFromFile([in] BSTR fName, [out, retval] BSTR *txtRet);

S>[id(2), helpstring("method Save2File")] HRESULT Save2File([in] BSTR fName, [in] BSTR txt2save);

S>V funkcii ReadFromFile ya prosto chitau text iz faila i vozvrashau ego.

S>I poluchau — error : Memory couldn't be 'written'
S>hotya tot zhe kod v obichnoi programme (ne v COM) rabotaet bezukoriznenno, edinstvennoe otlichie preobrazovanie iz char* v BSTR.

S>Esli uvazhaemie specialisti smogut vzglyanut' na privedennii nizhe code i ukazat' mne na oshibku budu priznatelen .




S>
S>STDMETHODIMP CFIO::ReadFromFile(BSTR fName, BSTR *txtRet)
S>{
S>    // TODO: Add your implementation code here
S>    USES_CONVERSION;
S>    _bstr_t bstrFName(fName,FALSE);
S>    HANDLE hFile;
S>    DWORD dwFileSize;
S>    DWORD dwBytesRead;
S>    BOOL bResult;
S>    char *pBuf;

S>    hFile = CreateFile(bstrFName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
S>    if (hFile == INVALID_HANDLE_VALUE) 
S>    {
S>        CloseHandle(hFile);
S>        return E_FAIL;
S>    }
S>    dwFileSize = GetFileSize(hFile,NULL);
S>    dwBytesRead = 0;
S>    if (dwFileSize == INVALID_FILE_SIZE)
S>    {
S>        CloseHandle(hFile); 
S>        return E_FAIL;
S>    } 
S>    pBuf = new char[dwFileSize];
S>    bResult = ReadFile(hFile,pBuf,dwFileSize,&dwBytesRead,NULL);
S>    if (bResult==0)
S>    {
S>        CloseHandle(hFile); 
S>        return E_FAIL;
S>    } 

S>    *txtRet = ::SysAllocString(A2OLE(pBuf));
S>//    delete pBuf;
S>    CloseHandle(hFile); 
S>    return S_OK;
S>}
S>


S>P.S.

S>proshu prosheniya za translit, poka u menya net drugoi vozmozhnosti beglo pisat' po russki

В какой момент ошибка?

Вобще-то меня подбивает-то, что ты нигде явно не ставишь нуль в конце строки
попробуй строку
pBuf = new char[dwFileSize];

заменить
pBuf = new char[dwFileSize+1];
ZeroMemory((PVOID)pBuf,dwFileSize+1);


Ну и конечно, CloseHandle(hFile); если dwFileSize == INVALID_FILE_SIZE, это тоже не к месту.
Но это так мелочь.

PS Поставь в Watch @Err,hr и посмотри, что API ф-и возвращают, особенно SysAllocString.
С уважением, OlegO.
Re: ReadFile from COMponent
От: Dront Россия  
Дата: 20.03.02 15:22
Оценка:
Здравствуйте sndralex, Вы писали:

S>Uvazhaemie Gospoda!

S>Pomogite razobrat'sya s problemoi:
S>Ya sozdau s pomosh'u ATL elementarnij COMponent s dvumya funkciyami:

<skipped>

S>

<skipped>

S>    pBuf = new char[dwFileSize];
S>    bResult = ReadFile(hFile,pBuf,dwFileSize,&dwBytesRead,NULL);
S>    if (bResult==0)
S>    {
S>        CloseHandle(hFile); 
S>        return E_FAIL;
S>    } 
S>    *txtRet = ::SysAllocString(A2OLE(pBuf));

<skipped>

S>


A2OLE (kak i voobshe SysAllocString) podrazumevajut, chto v pBuf lezhit NULL-terminated string. A u tebya fail vryad li nulem zakanchivaetsya. Poprobuj tak:
pBuf = new char[dwFileSize+1];pBuf[dwFileSize]=0;
WBR, Andrey Reznik (2:5020/2999, Andrey_Reznik@rambler.ru)
Re[2]: ReadFile from COMponent
От: sndralex Израиль www.gdetotam.co.il
Дата: 20.03.02 15:54
Оценка:
Здравствуйте Dront, Вы писали:

D>A2OLE (kak i voobshe SysAllocString) podrazumevajut, chto v pBuf lezhit NULL-terminated string. A u tebya fail vryad li nulem zakanchivaetsya. Poprobuj tak:

D>
D>pBuf = new char[dwFileSize+1];pBuf[dwFileSize]=0;
D>


Spasibo za vash otvet, no poka ne pomoglo. Ya vstavil rekomenduemii vami code
pBuf = new char[dwFileSize+1];pBuf[dwFileSize]=0;

Pri obrashenii k etoi funkcii iz VBClienta ya po prezhnemu poluchau "Memory couldn't be written", a esli prohozhu debuggerom to prohozhu vse do konca a po vihodu iz funkcii na
return S_OK;

ya poluchau soobshenie :
"User breakpoint called from code at 0xbla-bla"
i perehozhu na assembler.
Tolkom ne zanu eto govorit o kakoi-to oshibke ili eto normalnoe zavershenie funkcii .
Budu priznatelen za vashu pomosh'.
Alexander N. Treyner
Re: 2 IT
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.03.02 21:36
Оценка: 6 (1)
Привет.

Слушай, IT! Поставь в план тэг [translit], шоб он автоматом транслит на руский переводил.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: ReadFile from COMponent
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.03.02 21:50
Оценка: 6 (1)
Здравствуйте Dront, Вы писали:

S>> *txtRet = ::SysAllocString(A2OLE(pBuf));


A2OLE — занимает память в стеке. Так что если размер файла большой, то скорее всего пройдешся по памяти и перепишешь стек.

Лучше сражу занять память с помощью ::SysAllocStringByteLen (или как там ее):
    //pBuf = new char[dwFileSize];
    *txtRet = ::SysAllocStringByteLen(dwFileSize);
    bResult = ReadFile(hFile, txtRet, dwFileSize, &dwBytesRead, NULL);


PS
Вот только возвращать в VB бинарные данные в виде строки — это не очень хорошо. Здесь бы блольше подошол бы SAFEARRAY.

PPS
Это:
    if (hFile == INVALID_HANDLE_VALUE) 
    {
        CloseHandle(hFile);
        return E_FAIL;
    }

глупость. Достаточно будет:
    if(INVALID_HANDLE_VALUE == hFile) 
        return E_FAIL; // А здесь лучше описание человеческое засунуть, и ошибочку свою возвратить.

файл ведь не открылся...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: ReadFile from COMponent
От: Dront Россия  
Дата: 21.03.02 08:01
Оценка: 5 (1)
Здравствуйте sndralex, Вы писали:

К сказанному VladD2 добавить вроде нечего, но вот по поводу нижеотквоченного вопроса есть комментарий.

S>ya poluchau soobshenie :

S>"User breakpoint called from code at 0xbla-bla"
S>i perehozhu na assembler.
S>Tolkom ne zanu eto govorit o kakoi-to oshibke ili eto normalnoe zavershenie S>funkcii .
Дело в том, что в debug configuration VisualStudio "обрамляет" выделенные куски памяти символами 0xCC, чтобы потом по ним ловить ошибки с выделением памяти. Этот код, кроме прочего, соответствует ассемблерной команде int 3 (user breakpoint). Вывод: если в программе вываливается невесть откуда user breakpoint, ищи беды с пямятью, перезаписывающие код программы или стэк.
WBR, Andrey Reznik (2:5020/2999, Andrey_Reznik@rambler.ru)
Re[3]: ReadFile from COMponent
От: sndralex Израиль www.gdetotam.co.il
Дата: 21.03.02 08:42
Оценка:
Здравствуйте VladD2
Bolshoe spasibo za vashi soveti
Nakonec — to eto zarabotalo
Alexander N. Treyner
Re[2]: 2 IT
От: IT Россия linq2db.com
Дата: 21.03.02 17:20
Оценка:
Здравствуйте VladD2, Вы писали:

VD>Привет.


Вот именно.

VD>Слушай, IT! Поставь в план тэг [translit], шоб он автоматом транслит на руский переводил.


http://www.privet.com/decoder/
Если нам не помогут, то мы тоже никого не пощадим.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.