MSVC weigert sich Funktion in DLL zu exportieren.

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

MSVC weigert sich Funktion in DLL zu exportieren.

Beitrag von Aramis »

Ja, dies ist ein Versuch dieses Forum zu kultivieren und für Menschen nutzbar zu machen :-)

Problem ist dass sowohl VC8 als auch VC9 eine bestimmte Funktion zwar compilen, diese aber nicht in die Exporttabelle der generierten DLL übernehmen. Anders ausgedrückt: es ist nicht möglich sie von außen aufzurufen.

aiGetMaterialProperty
aiMaterial.h:1491
MaterialSystem.cpp:48

Die direkt darunter definierte/deklarierte Funktion (aiGetMaterialFloatArray) wird exportiert obwohl sie eine nahezu identische Signatur hat.
Wie gesagt, es ist mir ein Rätsel aber vielleicht übersehe ich auch bloß einen gigantischen Zauhpfahl der direkt vor mir in der Luft schwebt.

Any Hilfe or Hints ist highly erwünscht :-) ... wer sich das Projekt in Gänze angucken will darf das gerne tun:

Code: Alles auswählen

svn co https://assimp.svn.sourceforge.net/svnroot/assimp/trunk assimp 
Gruß,
Alex
odenter
Establishment
Beiträge: 207
Registriert: 26.02.2009, 11:58

Re: MSVC weigert sich Funktion in DLL zu exportieren.

Beitrag von odenter »

Haste ne *.def Datei erzeugt?
Wenn nicht damit sollte es gehen.

Hier eins meiner alten Beispiele:

Code: Alles auswählen

#include <windows.h>

signed long  _stdcall StdVar_Byte    (unsigned char     ByValValue,    unsigned char    *ByRefValue);
signed long  _stdcall StdVar_Integer (signed short int  ByValValue,    signed short int *ByRefValue);
signed long  _stdcall StdVar_Long    (signed long       ByValValue,    signed long      *ByRefValue);
signed long  _stdcall StdVar_Double  (double		    ByValValue,    double           *ByRefValue);
signed long  _stdcall StdVar_String  (char			    ByValValue[]);
signed long  _stdcall StdVar_Struktur(struct Struktur  *ByRefValue);
signed long  _stdcall Field_Byte     (unsigned char	    Field[],       signed long       nCount);
signed long  _stdcall Field_Integer  (signed short int  Field[],       signed long       nCount);
signed long  _stdcall Field_Long     (signed long 	    Field[],       signed long       nCount);


struct Struktur
{
	long x;
	char y;
};

//------------------------------------------------------------------------
// Die folgende Funktion unverändert belassen

BOOL WINAPI DllEntryPoint ( HINSTANCE hDLL, DWORD dwREASON, LPVOID Reserved )
{
	switch (dwREASON)
    { 
		case DLL_PROCESS_ATTACH: {
									break; 
								 }
		
		case DLL_PROCESS_DETACH: {
									break; 
								 } 		 
    }
	return TRUE;
}

//------------------------------------------------------------------------

signed long _stdcall StdVar_Byte (unsigned char ByValValue, char *ByRefValue)
{
	ByValValue++;
	*ByRefValue = *ByRefValue + 2;
	return (ByValValue);
}

//------------------------------------------------------------------------

signed long _stdcall StdVar_Integer (signed short int    ByValValue,    short int *ByRefValue)
{
	ByValValue++;
	*ByRefValue = *ByRefValue + 2;
	return (ByValValue);
}

//------------------------------------------------------------------------

signed long _stdcall StdVar_Long (signed long ByValValue, long *ByRefValue)
{
	ByValValue++;
	*ByRefValue = *ByRefValue + 2;
	return (ByValValue);
}

//------------------------------------------------------------------------

signed long _stdcall StdVar_Double (double ByValValue, double *ByRefValue)
{
	ByValValue++;
	*ByRefValue = *ByRefValue + 0.01;
	return (ByValValue);
}

//------------------------------------------------------------------------

signed long _stdcall StdVar_String  (char ByValValue[])
{
	
	int x;
		
		x=0;
		do
		{
			ByValValue[x]++;
			x++;
		}
		while (ByValValue[x]);

		return (x);
}

//------------------------------------------------------------------------


signed long  _stdcall StdVar_Struktur (struct Struktur *ByRefValue)
{
	(*ByRefValue).x += 11;
	(*ByRefValue).y += 1;
	return((*ByRefValue).x + (*ByRefValue).y);
}

//------------------------------------------------------------------------


signed long _stdcall Field_Byte (unsigned char Field[], long nCount)
{
	signed long Sum, z;

		Sum = 0;
		
		for (z = 0;z <= nCount; z++)
		{
			Field[z] +=1;
			Sum += Field[z];
		}
		
		return (Sum);
}

//------------------------------------------------------------------------

signed long _stdcall Field_Integer (signed short int Field[], long nCount)
{
	signed long Sum, z;

		Sum = 0;
		
		for (z = 0; z <= nCount; z++)
		{
			Field[z] += 1;
			Sum += Field[z];
		}
		
		return (Sum);
}

//------------------------------------------------------------------------

signed long _stdcall Field_Long (signed long Field[], long nCount)
{
	signed long Sum, z;

		Sum = 0;
		
		for (z = 0;z <= nCount; z++)
		{
			Field[z] += 1;
			Sum += Field[z];
		}
		
		return (Sum);
}
Und die *.def Datei:

Code: Alles auswählen

;------------------------------------------------------------------------
LIBRARY test_dll

CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD SINGLE

EXPORTS
StdVar_Byte @1
StdVar_Integer @2
StdVar_Long @3
StdVar_Double @4
StdVar_String @5
StdVar_Struktur @6
Field_Byte @7
Field_Integer @8
Field_Long @9
;------------------------------------------------------------------------
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: MSVC weigert sich Funktion in DLL zu exportieren.

Beitrag von kimmi »

Was sagt denn Dumpbin, ist das Symbol überhaupt in der Export-Lib oder nicht?

Gruß Kimmi
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: MSVC weigert sich Funktion in DLL zu exportieren.

Beitrag von Aramis »

Moin,
Was sagt denn Dumpbin, ist das Symbol überhaupt in der Export-Lib oder nicht?
Nein, ist auch da nicht vorhanden.
Haste ne *.def Datei erzeugt?
Hm, def-Dateien wären eine Möglichkeit aber sind halt ein zusätzlicher Pflegeaufwand und potentielle Fehlerursache, was ich bei Assimp momentan nicht riskieren will :? Außerdem sind es nicht nur C-Exporte sondern auch welche aus einem C++-Scope, da bin ich ehrlich gesagt überfragt ob das mit DEF-Files überhaupt geht. Prizipiell muss es der Compiler ja auch so hinkriegen ...

btw.: ASSIMP_API wird, wie üblich, entweder __declspec(dllexport) oder __declspec(dllimport). Die Zuordnung ist eindeutig richtig, denn andere Funktionen werden ja exportiert.

Danke für eure Hilfe :-)

Gruß,
Alex
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: MSVC weigert sich Funktion in DLL zu exportieren.

Beitrag von kimmi »

Hast du dich eventuell mit den extern-c Export-infos vertan? Da fliegen ja relativ viele Makros rum. Kommentier die doch mal aus, schreib es in Reinform hin und suche das Symbol. Geht es dann, trage nach und nach die Makros wieder ein, bis du den Bug hast. Von .def Files würde ich ebenfalls Abstand nehmen. Die Exportlibs funktionieren ja eigentlich recht zuverlässig.

Gruß Kimmi
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: MSVC weigert sich Funktion in DLL zu exportieren.

Beitrag von Aramis »

Habe ich soeben nochmals gemacht, die Ursache ist für mich immer noch nicht ersichtlich. Langsam aber sicher bin ich soweit es als Compilerbug zu deklarieren, würde ich zumindest gerne :-)

Wenn ich alle Kommentare rauslasse sieht die Deklaration so aus:

Code: Alles auswählen

// nicht exportiert
ASSIMP_API C_ENUM aiReturn aiGetMaterialProperty(
	const C_STRUCT aiMaterial* pMat, 
	const char* pKey,
	C_ENUM aiTextureType type,
    	unsigned int  index,
    	const C_STRUCT aiMaterialProperty** pPropOut);

// exportiert
ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray(
	const C_STRUCT aiMaterial* pMat, 
	const char* pKey,
	unsigned int type,
	unsigned int index,
	float* pOut,unsigned int* pMax);
Dasselbe gilt für die Definition beider Funktionen! Direkt untereinander, ohne jegliche Makroänderungen dazwischen.

Gruß,
Alex
Gelöschter Benutzer
Beiträge: 92
Registriert: 26.02.2009, 22:09

Re: MSVC weigert sich Funktion in DLL zu exportieren.

Beitrag von Gelöschter Benutzer »

:!: Was mir noch einfällt, da ich sowas auch bei mir schon hatte:

Wenn du das in eine Klasse als statische Methode integrierst, z.B. so:

Code: Alles auswählen

class __declspec(dllexport) AssimpFunctions
{
    static aiReturn aiGetMaterialProperty(const aiMaterial* pMat, const char* pKey,
                                          aiTextureType type, unsigned int  index,
                                          const aiMaterialProperty** pPropOut);
};
Werden dann die Funktionen exportiert (sprich: Sagt DepencyWalker "hab ich!")?

Später im Code kannst du dann ja ein Define einrichten, damit es keine Kompabilitätsprobleme gibt:

Code: Alles auswählen

#define aiGetMaterialProperty(pMat, pKey, type, index, pPropOut) AssimpFunctions::aiGetMaterialProperty(...)
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: MSVC weigert sich Funktion in DLL zu exportieren.

Beitrag von Aramis »

Hm ... das würde natürlich gehen, fällt jedoch eher in die Kategorie dreckiger Hacks/Workarounds ... (jah, verlockende Sache aber ich bin bemüht mir alle diesbezüglichen Ambitionen abzugewöhnen :-)).

Momentan sind ja noch nicht so viele Leute hier unterwegs, daher lasse ich das jetzt einfach mal so stehen wie es ist. Vielleicht findet ja irgendjemand noch was ... die Hoffnung stirbt bekanntlich zuletzt, von Chuck Norris mal abgesehen.

Alex
Antworten