Problem mit Funktionszeigern

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
dawit
Beiträge: 42
Registriert: 05.02.2011, 17:06

Problem mit Funktionszeigern

Beitrag von dawit »

Hallo alle zusammen

Um Ressourcen, die ich mit DevIL geladen habe, auch nach dem Wurf einer Exception sicher wieder zu löschen, habe ich eine kleine Klasse geschrieben, die die von DevIL zurückgebene ID im Destruktor via ilDeleteImages(ILsizei num, const ILuint *images) wieder löscht. Da man so eine Funktionalität auch allgemein für z.B. OpenGL verwenden kann, hab ich mir mal gedacht, dass man der Klasse im Konstruktor einfach einen Funktionszeiger übergibt, die dann zum Löschen verwendet wird.

Das ganze sieht dann so aus:

Code: Alles auswählen

template<typename IDType, typename SizeType>
class ScopedID
{
public:

	typedef void (*DeleteFunc)(SizeType num, IDType const *id);

	ScopedID(DeleteFunc del) : mID(0)  
	{
		mDelete = del;
	}
	ScopedID(IDType id, DeleteFunc del) : mID(id)  
	{
		mDelete = del;
	}
	~ScopedID()
	{
		mDelete(1, &mID);
		mID = 0;
	}
	
	operator IDType* ()  { return &mID; }
	operator IDType ()  { return mID; }
	
private:
	IDType mID;
	DeleteFunc mDelete;
};
Benutzen tu ich das ganze so:

Code: Alles auswählen

ScopedID<ILsizei, ILuint> id(ilDeleteImages);
Mit dem gcc unter Linux hat auch alles geklappt, aber mit mingw unter Windows beschwert sich der Compiler folgendermaßen:
error: invalid conversion from 'void (*)(ILsizei, const ILuint*)' to 'void (*)(unsigned int, const unsigned int*)'
error: initializing argument 1 of 'Kaos::ScopedID<IDType, SizeType>::ScopedID(void (*)(SizeType, const IDType*)) [with IDType = unsigned int, SizeType = unsigned int]'


Ich hab auch schon im Header von DevIL nachgeschaut, und ILsizei ist ein typedef auf size_t (was wiederum ein unsigned int ist) und GLuint ist (überraschenderweise) ein unsigned int.
Eigentlich ist meiner Meinung nach also alles in Ordnung (allerdings ist mein Compiler irgendwie recht häufig anderer Meinung als ich, wobei es so langsam immer besser wird)

Als ich eine Testfunktion foo(ILsizei num, const ILuint *images) an den Konstruktor übergeben habe, hat auf einmal alles geklappt.

Hat vielleicht jemand eine Idee woran es liegen könnte?
Benutzeravatar
Krishty
Establishment
Beiträge: 8350
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Problem mit Funktionszeigern

Beitrag von Krishty »

Nur drübergeguckt, aber: SizeType ist dein zweiter Template-Parameter, IDType der erste. Sollte das nicht umgekehrt sein? Jedenfalls gibst du es überall umgekehrt an.

template<typename IDType, typename SizeType> class ScopedID
vs.
ScopedID<ILsizei, ILuint>

Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
dawit
Beiträge: 42
Registriert: 05.02.2011, 17:06

Re: Problem mit Funktionszeigern

Beitrag von dawit »

Stimmt, das ist ein bisschen inkonsistent, ist aber leider richtig so (werd's aber trotzdem mal ändern)
Benutzeravatar
Krishty
Establishment
Beiträge: 8350
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Problem mit Funktionszeigern

Beitrag von Krishty »

Habe es bei mir weitestmöglich getestet und dein Text sieht korrekt aus. Die Fehlermeldung klingt auch sinnlos. Sicher, dass ilDeleteImages(…) nicht noch weiter dekoriert wurde, z.B. mit einer anderen Aufrufkonvention?

Lese ich recht, dass es funktioniert hat, bevor du den neuen K’tor (den ohne ID) eingeführt hast?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
dawit
Beiträge: 42
Registriert: 05.02.2011, 17:06

Re: Problem mit Funktionszeigern

Beitrag von dawit »

Nee, tut mir leid, da hab ich mich vielleicht undeutlich ausgedrückt: mit dem zweiten Konstruktor hat es nichts zu tun, jedoch hat der selbe Code unter linux fehlerlos kompiliert.
Wenn ich statt ilDeleteImages die leere Funktion foo(ILsizei, ILuint const *) an egal welchen Konstruktor übergebe, funktioniert es.
Bin da gerade ein bisschen ratlos.
Naja, ich werde mir jetzt nochmal die Header von DevIL ansehen
dawit
Beiträge: 42
Registriert: 05.02.2011, 17:06

Re: Problem mit Funktionszeigern

Beitrag von dawit »

Krishty, du hattest recht. Vor der Funktionsdeklaration stand noch nettes ILAPIENTRY, definiert als __stdcall.

Wenn man den Funktionspointer entsprechend anpasst, funktioniert alles:

Code: Alles auswählen

typedef void (__stdcall *DeleteFunc)(SizeType num, IDType const *id);
Danke!
Antworten