» »

[c++] prenos po referenci

[c++] prenos po referenci

atasmrk ::

Delam si wraper funkcij, ki delajo s printerjem v Win32. Tako sem si napisal funkcijo
int enumeratePrinters(PRINTER_INFO_2 *printers);

ta funkcija vrne stevilo tiskalnikov, ki so priklopljeni na racunalnik (lokalo ali preko mreze) in klice spodnjo funkcijo:
BOOL EnumPrinters(
  DWORD Flags,         // printer object types
  LPTSTR Name,         // name of printer object
  DWORD Level,         // information level
  LPBYTE pPrinterEnum, // printer information buffer
  DWORD cbBuf,         // size of printer information buffer
  LPDWORD pcbNeeded,   // bytes received or required
  LPDWORD pcReturned   // number of printers enumerated
);

ki je bolj natancno dokumentirana v MSDN-ju. Uporabljam pa jo na nacin, ki ga Microsoft priporoca na tej povezavi

Sedaj pa porblem.

Znotraj funkcije
enumeratePrinters()
je vse v redu, struktura je lepo zapolnjena (razen prvega polja strukture, tam mi debug kaze slab kazalec), zunaj te funkcije (v Main) pa ni opazne razlike. To ap me bega. V glavo se mi je namrec zasidralo dejstvo, da posredovanje kazalcev pomeni prenos po referenci.

desperados ::

še na kodirnici povprašaj
morda ti tam pomagajo, osebno se pa ne ukvarjam z tako "naprednimi" funkcijami jezika

Zgodovina sprememb…

Vesoljc ::

pokazi kodo :\
Abnormal behavior of abnormal brain makes me normal...

atasmrk ::

Dobro, celoten listing:

Printer.h:

#ifndef Printer_h
#define Printer_h

#include <Windows.h>
#include <Winspool.h>
#include <Stdio.h>

int enumeratePrinters(PRINTER_INFO_4 *printers);

#endif


Printer.cpp:

#include "Printer.h"

int enumeratePrinters(PRINTER_INFO_4 *printers)
{
	DWORD numPrinters;
	DWORD bufferSize;

	if (!(EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &bufferSize, &numPrinters)))
	{
		if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
		{
			printf("Unknown error; terminating program\n");
			return (-1);
		}
	}

	if ((printers = (PRINTER_INFO_4 *)malloc(bufferSize)) == NULL)
	{
		printf("Failed to allocate memory for PRINTER_INFO_2 structure, terminating program\n");
		return (-1);
	}
	
	if (!(EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, (LPBYTE)printers, bufferSize, &bufferSize, &numPrinters)))
	{
		printf("Failed to extract printer info, terminating program\n");
		free(printers);
		return (-1);
	}

	return (int)numPrinters;

}


Mani.cpp
#include "Printer.h"


int main(int argc, char *argv[])
{
	int numPrinters;
	PRINTER_INFO_4 *printers;

	numPrinters = 0;
	printers = NULL;

	numPrinters = enumeratePrinters(printers);

	printf("Number of all printers: %d", numPrinters);
	for(int i = 0; i < numPrinters; i++)
	{
		printf("Printer %d\t%s\n", i, printers[i].pPrinterName);
	}

	return 0;
}

Zgodovina sprememb…

  • spremenilo: atasmrk ()

SasoS ::

Sam pointer ne pomeni prenašanje po referenci. Pointerji se prenašajo po vrednosti, ker pa vsi kažejo na isto lokacijo se tisto kamor kaže pointer prenaša po referenci...recimo.

V enumeratePrinters nardiš:
if ((printers = (PRINTER_INFO_4 *)malloc(bufferSize)) == NULL)

S tem kazalec printers ne kaže več na isto lokacijo kot tisti v main funkciji. Alociraj spomin v main funkciji.

Zgodovina sprememb…

  • spremenilo: SasoS ()

atasmrk ::

Hvala vam usem. Zadevo resil. Da bi celoten prostor rezerviral kar v Main.u mi ni bilo vsec, potem bi imel polno smetenja s kodo tam kjer ga nocem. Pa sem naredil nekaj drugega. v Main sem namesto
printers = NULL;
napisal
printers = (PRINTER_INFO_4 *)malloc(sizeof(PRINTER_INFO_4));
Tako sem dobil prostor za eno strukturo. V enumeratePrinters() pa sem namesto malloc() uporabil:
if ((printers = (PRINTER_INFO_4 *)realloc(printers, bufferSize)) == NULL)
[edit]Sedajle sem sel se enkrat cez dokumentacijo za realloc() in tukajle pise, da se lahko zgodi, da realloc premakne rezervirani kos pomnilnika. Torej mi stvar nacelno dela, vcasih pa lahko propade.
Kako pa bi stvar izgledala s kazalcem na kazalec? Saj je to rocica, ne?

Zgodovina sprememb…

  • spremenilo: atasmrk ()

SasoS ::

ni dobro. Za realloc ti noben ne garantira da bo to isti kos memorije...

atasmrk ::

Ja, sem pisal edit, ko si me opozoril na to. Torej se enkrat: kako bi stvar izgledala s kazalcem na kazalec?

SasoS ::

v mainu
numPrinters = enumeratePrinters(&printers);


spremeni
int enumeratePrinters(PRINTER_INFO_4 **printers)
{
...
if (!printers || (*printers = (PRINTER_INFO_4 *)malloc(bufferSize)) == NULL)
...
if (!(EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, (LPBYTE)*printers, bufferSize, &bufferSize, &numPrinters)))
...

atasmrk ::

Hvala lepa. Deluje tako kot mora.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

C in funkcije ter #define

Oddelek: Programiranje
463939 (2300) misek
»

C programiranje (strani: 1 2 3 )

Oddelek: Programiranje
14127704 (18000) amacar
»

[C] Povezani seznami in kazalci

Oddelek: Programiranje
242563 (2130) Good Guy
»

[ C ] floating point not loaded !!?

Oddelek: Programiranje
111555 (1488) Fizikalko
»

[.NET ali c#] ne najdem dokumentacije

Oddelek: Programiranje
81457 (1303) atasmrk

Več podobnih tem