Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Différence entre GlobalAlloc et new

4 réponses
Avatar
Stéphane Vasseur
j'ai un petit soucis je compilais un programme sous Xp qui marchais
parfaitement hors sous Seven paf le crash.

le probl=E8me viens de l'allocation m=E9moire je pense.

char *bufferjpeg =3D new char[Taillemax];

apr=E8s je charge mon fichier jpeg dans bufferjpeg.
et j=92appelle une routine pour afficher le jpeg dont le d=E9but fait :

long pictureWidth, pictureHeight;
char *dataptr;
HGLOBAL hGlobal;
LPSTREAM pictureStreamPtr;
LPPICTURE picture;

HBITMAP memBitmap, oldBitmap;
HDC memDC;
void *pixelptr;
BITMAPINFO bmi;
CreateStreamOnHGlobal((void*)bufferjpeg, TRUE, &picturestreamptr);
OleLoadPicture(picturestreamptr, 0, FALSE, IID_IPicture , (LPVOID
*)&picture);
picture->get_Width(&picturewidth);
a partir de la =E7a crash sous Seven mais pas sous XP !

en gros il as pas aim=E9 je suppose ma conversion de ma m=E9moire allouer
par new en
(void*) qui est normalement un pointeur Hglobal.


si je fait =E0 la place :

char *bufferjpeg =3D new char[Taillemax];

Je charge mon fichier jpeg dans bufferjpeg.
puis j=92appelle une routine pour afficher le jpeg dont le d=E9but fait :

hGlobal =3D GlobalAlloc(GMEM_MOVEABLE, Taillemax);
dataptr =3D (char*) GlobalLock(hGlobal);
for (t =3D 0 ; t < 1280 * 1024 * 3 ; t++)
*dataptr++ =3D bufferjpeg[t];
CreateStreamOnHGlobal(hGlobal, TRUE, &pictureStreamPtr);
OleLoadPicture(pictureStreamPtr, 0, FALSE, IID_IPicture , (LPVOID
*)&picture);
picture->get_Width(&pictureWidth);

=E7a marche sous Seven et XP. seulement =E7a m'oblige a faire une copie
des donn=E9es d=E9j=E0 charg=E9es alors que avec ma m=E9thode
je lui passais directement le pointeur de mes donn=E9es.

ma question une id=E9e de pourquoi =E7a marche plus sous SEVEN ?
J'ai chercher un peu sur google et j'ai vu que c=92=E9tait m=EAme pas bien
d'utiliser GlobalAlloc c'est vrai ?
en gros il y a un autre moyen pour cr=E9er un stream directement sur ma
m=E9moire allouer par new ?

je maitrise assez mal les objet OLE il y a surement quelque chose de
simple que je n'es pas compris.
mais je trouvais sa pratique pour afficher du jpeg en quelques ligne.

4 réponses

Avatar
Christian ASTOR
Stéphane Vasseur a écrit :

ma question une idée de pourquoi ça marche plus sous SEVEN ?
J'ai chercher un peu sur google et j'ai vu que c’était même pas bien
d'utiliser GlobalAlloc c'est vrai ?
en gros il y a un autre moyen pour créer un stream directement sur ma
mémoire allouer par new ?



Pour charger un fichier dans stream avec HGLOBAL, on fait en principe
comme ça =>
(pas testé sous Seven...)
(sinon il y a de nombreux autres moyens pour charger des JPG simplement)

LPPICTURE gpPicture;
HGLOBAL hGlobal;
LPVOID pvData = NULL;
DWORD dwFileSize;
HANDLE hFile = CreateFile("foo.jpg", GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
dwFileSize = GetFileSize(hFile, NULL);
if (dwFileSize != -1)
{
hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
if (hGlobal != NULL)
{
pvData = GlobalLock(hGlobal);
if (pvData != NULL)
{
DWORD dwBytesRead = 0;
BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
if (bRead)
{
GlobalUnlock(hGlobal);
CloseHandle(hFile);
}
}
}
}
}

LPSTREAM pstm = NULL;
HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
if (SUCCEEDED(hr) && pstm)
{

hr = OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID
*)&gpPicture);
if (SUCCEEDED(hr) && gpPicture)
{
pstm->Release();
// ... etc
Avatar
Stéphane Vasseur
merci Christian de m'avoir répondu mais en fait j'ai dut mal
m'exprimer,

Je sais que si j'utilise GlobalAlloc ca marche.
Cependant je veut passer par un new ou tout autre forme de buffer que
j'aurais déjà crée en mémoire sans justement appeler GlobalAlloc.

et donc moi au lieu de la ligne :
CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);

je faisait :
CreateStreamOnHGlobal((void*)bufferjpeg, TRUE, &pstm);

bufferjpeg étant le buffer qui contiens mon image jpeg.
qui est créer sans passer par GlobalAlloc :

char *bufferjpeg = new char[taille]; tout simplement

donc ce code la marchais très bien Sous XP et ca plante sous Seven

La question est donc y a t'il un autre moyen pour créer un stream
directement sur mon buffer, une autre fonction ?

(sinon il y a de nombreux autres moyens pour charger des JPG
simplement)

je suis preneur mais je veut pas passer par une librairie externe
etc...
Avatar
Christian ASTOR
Stéphane Vasseur a écrit :
merci Christian de m'avoir répondu mais en fait j'ai dut mal
m'exprimer,

Je sais que si j'utilise GlobalAlloc ca marche.
Cependant je veut passer par un new ou tout autre forme de buffer que
j'aurais déjà crée en mémoire sans justement appeler GlobalAlloc.



Mais, ce n'est pas bon.
Il faut un HGLOBAL, c'est construit comme ça.
GlobalAlloc() appelle RtlAllocateHeap() sur RtlProcessHeap()
new() appelle HeapAlloc() qui appelle RtlAllocateHeap() sur _crtheap


(sinon il y a de nombreux autres moyens pour charger des JPG
simplement)
je suis preneur mais je veut pas passer par une librairie externe
etc...



Oui, on n'a jamais besoin de lib externes sous Windows, tout est inclus
dans l'api (interfaces comme IThumbnail pour les JPG)
Avatar
torri
On Fri, 01 Apr 2011 12:33:40 +0200, Christian ASTOR wrote:

Oui, on n'a jamais besoin de lib externes sous Windows, tout est inclus
dans l'api (interfaces comme IThumbnail pour les JPG)



je ne veux pas troller, mais je doute quant à cette assertion. Windows
peux lire en natif les fichier jpeg2000, dvi, djvu, comic book, ... ?