Newsgroup: it.comp.lang.c++
Titolo: 'sto VC++ vuole sapere troppo...

Mi', ho dichiarato un puntatore a un tipo di dati (che dovevo usare per
delle API), lo compilo e quel compilatore porco me lo punta a 0x0000013f,
un'altra volta a 0x00000000, dove manco Bill in persona ci può appena
guardare se quarantamila processi non gli danno il permesso. Intanto legge
tranquillamente, e appena ci scrive, indovinate un po' (e meno male), Access
Violation. E' scemo o cosa? Ditemelo voi...
--
E.G. er Cicca
er_c...@excite.com
ICQ # 18872702
"Art. 1: L'Italia è una Repubblica progettata per Windows 98."

 Violation. E' scemo o cosa? Ditemelo voi...
Posta il codice che diagnostichiamo
--== Sent via Deja.com 
http://www.deja.com/
 ==--
---Share what you know. Learn what you don't.---

 Violation. E' scemo o cosa? Ditemelo voi...
Hai inizializzato il pointer?  Oppure stai sovrascrivendo la tua memoria?
-- 
Maurizio Loreti                      
http://wwwcdf.pd.infn.it/~loreti/mlo.html
Un. of Padova, Dept. of Physics - Padova, Italy          
lor...@padova.infn.it

 Posta il codice che diagnostichiamo
Ecco qua:
class CModem {
 HANDLE hCommWrite;
 HANDLE hCommRead;
public:
 void SetProp(
    int CommPort = 2,
    DWORD Speed = CBR_9600,
    BYTE Bits = 8,
    BYTE Parity = NOPARITY,
    BYTE StopBits = ONESTOPBIT) {
  // Definisce le impostazioni di sicurezza
  SECURITY_ATTRIBUTES Sec;
  Sec.nLength = sizeof(SECURITY_ATTRIBUTES);
  Sec.lpSecurityDescriptor = NULL;
  Sec.bInheritHandle = TRUE;
  // Imposta la stringa di creazione del file
  char cpfile[9] = "\\\\.\\COMx";
  cpfile[7] = (char)CommPort + 0x30;
  // Apre la porta di scrittura e lettura e riceve l'handle
  hCommWrite = CreateFile(cpfile, GENERIC_WRITE, 0,
   &Sec, OPEN_EXISTING,
   FILE_ATTRIBUTE_NORMAL +
   FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  hCommRead = CreateFile(cpfile, GENERIC_READ, 0,
   &Sec, OPEN_EXISTING,
   FILE_ATTRIBUTE_NORMAL +
   FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  // Imposta la porta
  DCB* lpdcb;   // <--- lpdcb punta a una locazione qualsiasi
  GetCommState(hCommWrite, lpdcb);   // <--- Qui mi segnala un Access
Violation su KERNEL32.DLL, e continua
  lpdcb->BaudRate = Speed;  // <--- Un altro Access Violation e si ferma lě.
  lpdcb->ByteSize = Bits;
  lpdcb->Parity = Parity;
  lpdcb->StopBits = StopBits;
  SetCommState(hCommWrite, lpdcb);
 }
 void Write(LPCVOID str) {
  LPDWORD lpBytesWritten;
  WriteFile(
   hCommWrite,
   str,
   sizeof(str),
   lpBytesWritten,
   NULL);
 }
};

Violation su KERNEL32.DLL, e continua
La struttura DBC deve essere allocata _prima_ di passarla alla funzione, che
si limita solo a valorizzare i vari campi:
DBC dcb;
/*questo forse non è necessario per la struttura DCB, ma in molti casi le
API sono "schizzinose" se le strutture non sono inizializzate
correttamente*/
memset(&dcb,0,sizeof(DCB));
dcb.DCBLength=sizeof(DCB);
GetCommState(handle,&dcb);
In alcuni casi (TAPI, ma non solo) sono necessarie due chiamate: una per
farsi tornare la dimensione della struttura e una per leggere i dati (dopo
aver opportunamente riallocato la struttura).
Tieni presente che generalmente le API non allocano memoria e, in quei casi,
richiedono un puntatore a puntatore come parametro (o ritornano un
puntatore).
---
Valter Minute
min...@fortech.it
 (the reply address of this message is invalid)
---
Are you looking for a good freeware ScreenSaver? Try FOYD!
http://hotfiles.zdnet.com/cgi-bin/texis/swlib/hotfiles/getit.bin?fcode=000PZ
0
if you want, I can send you the (free) C++ source code.


ICQ #34602650


[...]
Prova così...
   // Imposta la porta
   DCB dcb;
   GetCommState(hCommWrite, &dcb);
   dcb.BaudRate = Speed;
   dcb.ByteSize = Bits;
   dcb.Parity = Parity;
   dcb.StopBits = StopBits;
   SetCommState(hCommWrite, &dcb);
Ricorda che un puntatore deve "puntare" ad un indirizzo di memoria
valido. Ovviamente, se definisci il puntatore, esso conterrà un
valore del tutto casuale ed arbitrario e la tua applicazione si
pianterà.
Per risolvere il problema, in questo caso, ho utilizzato una
variabilie locale. Se desideri utilizzare un puntatore, usa gli
operatori new e delete (o malloc/free) per acquisire una certa
quantità di memoria ed assegnarne l'indirizzo al puntatore.
   DCB* lpdcb;
   lpdcb = new DCB;
   GetCommState(hCommWrite, lpdcb);
   lpdcb->BaudRate = Speed;
   lpdcb->ByteSize = Bits;
   lpdcb->Parity = Parity;
   lpdcb->StopBits = StopBits;
   SetCommState(hCommWrite, lpdcb);
   delete lpdcb;
Aldo