CG dlls aus Unterordner laden.

nchristoph

Erfahrenes Mitglied
Hallo.

Ich bin gerade beim herumprobieren mit dem CG Devkit. Hab auch schon nen Wassershader gemacht. Hab jetzt aber das Problem, das die cg.dll und cgGL.dll im Verzeichnis mit der exe liegen müssen, damit das Spiel startet.

Wie schaffe ich das, das die dll dateien aus dem Verzeichnis lib geladen werden?

Ich hab mir mal eine Funktion gebastelt und die in der Init Funktion des Spiels aufrufen lassen, allerdings ohne Erfolg.

Code:
void LoadLibrarys(void)
{
	char sz[256];
	char sz2[256];
	char sz3[256];

	sprintf(sz, "%s/lib/cg.dll", gEngfuncs.pfnGetGameDirectory());
	sprintf(sz2, "%s/lib/cgGL.dll", gEngfuncs.pfnGetGameDirectory());
	sprintf(sz3, "%s/lib/opengl32.dll", gEngfuncs.pfnGetGameDirectory());

	LoadLibrary(sz);
	LoadLibrary(sz2);
	LoadLibrary(sz3);
}

Lt. Console werden die Dateien geladen, allerdings crasht das Spiel dann wenn ich auf einem anderen Pc als meinen Entwicklungspc Testen will.

Ich arbeite mit VC++ 6.0, SetDLLDirectory/GetDLLDirectory fällt da wohl flach oder?.

Kann mir wer helfen?

Danke für die Hilfe
 
Zuletzt bearbeitet:
Hallo,

Sind die Dateien den auf den anderen PC's installiert?
Bzw. Funktioniert es bei dir wenn du es mit VC startest und wenn du es einfach über die .EXE startest?

Falls es über die EXE auch bei dir nicht geht liegen die DLL's nicht im richtigen Verzeichnis.

Gruß
Anfänger
 
Wenn die dlls im exe Ordner drinnen sind, läd der Mod ja ohne Probleme.

Ich will aber nicht, das durch meine dlls andere Mods unbrauchbar werden, daher muss ich die irgendwie aus nem unterordner laden lassen, ohne das ich mir alles zerknalle.

Hab mich jetzt mal durch die MSDN gewühlt und meine funktion dementsprechend umgeschrieben.

Code:
void LoadLibrarys(void)
{
	HINSTANCE	m_hcgdll;
	HINSTANCE	m_hcggldll;
	HINSTANCE	m_hopengl;

	char cgdll[256];
	char cggldll[256];
	char opengldll[256];

	sprintf( cgdll, "%s/lib/cg.dll", gEngfuncs.pfnGetGameDirectory());
	// replace forward slashes with backslashes
	for( int i=0; i < 256; i++ )
		if( cgdll[i] == '/' ) cgdll[i] = '\\';
	
	m_hcgdll = LoadLibrary( cgdll );

	if( m_hcgdll != NULL )
	{
			FreeLibrary( m_hcgdll );
			gEngfuncs.Con_Printf("CG Error: cg.dll function table invalid, not loading\n");
			return;
		
	} 
	else
	{
		gEngfuncs.Con_Printf("CG Error: cg.dll invalid, not loading\n");
		return;
	}
		
	sprintf( cggldll, "%s/lib/cgGL.dll", gEngfuncs.pfnGetGameDirectory());
	// replace forward slashes with backslashes
	for( int j=0; j < 256; j++ )
		if( cggldll[j] == '/' ) cggldll[j] = '\\';
	
	m_hcggldll = LoadLibrary( cggldll );

	if( m_hcggldll != NULL )
	{
			FreeLibrary( m_hcggldll );
			gEngfuncs.Con_Printf("CG Error: cgGL.dll function table invalid, not loading\n");
			return;
		
	} 
	else
	{
		gEngfuncs.Con_Printf("CG Error: cgGL.dll invalid, not loading\n");
		return;
	}
		
	sprintf( opengldll, "%s/lib/opengl32.dll", gEngfuncs.pfnGetGameDirectory());
	// replace forward slashes with backslashes
	for( int k=0; k < 256; k++ )
		if( opengldll[k] == '/' ) opengldll[k] = '\\';
	
	m_hopengl = LoadLibrary( opengldll );

	if( m_hopengl != NULL )
	{
			FreeLibrary( m_hopengl );
			gEngfuncs.Con_Printf("Opengl Error: opengl32.dll function table invalid, not loading\n");
			return;
		
	} 
	else
	{
		gEngfuncs.Con_Printf("Opengl Error: opengl32.dll invalid, not loading\n");
		return;
	}


}

Funktioniert allerdings immer noch nicht. Dlls werden nicht geladen, obwohl der ordner stimmt.
 
Zuletzt bearbeitet:
Ok ich hab mich nochmal dahinter geklemmt und bin jetzt soweit bekommen.

PHP:
CShader::LoadLibrarys(void)
{
	char libdir[256];
	 
	sprintf(libdir, "%s/lib/", gEngfuncs.pfnGetGameDirectory());

	if(libdir == NULL) {
		SetDllDirectoryA(libdir);
        gEngfuncs.Con_Printf("SetDllDirectory successful\n");
		gEngfuncs.Con_Printf(libdir);
    } else {
        gEngfuncs.Con_Printf("SetDllDirectory failed\n");
    }
	HINSTANCE m_hcgdll = LoadLibraryEx("cg.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
    if(m_hcgdll != NULL) {		 
        gEngfuncs.Con_Printf("dll loaded\n");
		if(m_hcgdll == NULL){   
        gEngfuncs.Con_Printf("dll  failed\n");
		}
	}
}

Problem ist jetzt, das SetDLLDirectory zwar richtig ausgegeben wird, LoadLibraryEx aber immer true zurückgibt.

Ich hab von Windows Programmierung nicht wirklich ne Ahnung. Wie kann ich HINSTANCE richtig überprüfen?
 
Hi.
C:
CShader::LoadLibrarys(void)
{
	char libdir[256];
	 
	sprintf(libdir, "%s/lib/", gEngfuncs.pfnGetGameDirectory());

	if(libdir == NULL) {
Wie sollte denn libdir NULL sein? Das ist ein statisches Array welches vom Compiler angelegt wird. Das ist niemals NULL.

Du solltest besser tatsächlich den Erfolg der SetDllDirectory Funktion überprüfen (liefert 0 zurück wenn nicht erfolgreich, siehe MSDN).

C:
	HINSTANCE m_hcgdll = LoadLibraryEx("cg.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
Du gibst hier LOAD_WITH_ALTERED_SEARCH_PATH als Flag an. Laut MSDN mußt du dann einen absoluten Pfad übergeben, ansonsten ist das Verhalten der Funktion undefiniert.

Wenn du LOAD_WITH_ALTERED_SEARCH_PATH und einen absoluten Pfad angibst, dann brauchst du SetDllDirectory nicht aufrufen.

Gruß
 
Danke erstmal für die Antwort.

Ich werd aus dem MSDN gedöns ned schlau.

Egal wie ichs überprüfe, es wird immer Successfull angezeigt.

Sowohl auf diesem PC als auch auf dem Laptop, wo der Ordner noch NIE existiert hat und auch jetzt nicht existiert
 
Zuletzt bearbeitet:
Danke erstmal für die Antwort.

Ich werd aus dem MSDN gedöns ned schlau.

Egal wie ichs überprüfe, es wird immer Successfull angezeigt.

Sowohl auf diesem PC als auch auf dem Laptop, wo der Ordner noch NIE existiert hat und auch jetzt nicht existiert
Es ist auch irrelevant ob das Verzeichnis existiert. Die SetDllDirectory Funktion signalisert bei erfolgreichem Hinzufügen des Pfades zur internen Liste Erfolg oder auch nicht; es wird nicht überprüft ob der Pfad existiert - oder hast du etwas in der Richtung im MSDN gelesen?

Gruß
 
Aso dann ist klar.

Wie kann ich dann testen, ob der Pfad existent ist? Will ja Sicher sein, das das ganze Funktioniert.
 
Ok ich hab mich jetzt quer durch Google gewühlt.

Soweit ich da herausgefunden habe, werden die CG dlls und auch die opengl32.dll direkt durch die exe geladen.

Mit SetDllDirectory gebe ich der exe den Suchpfad vor, wo sie nach den dlls suchen muss oder?

Im Fall der CG dlls und opengl32.dll brauch ich dann ja den LoadLibrary aufruf nicht mehr oder hab ich das falsch verstanden?
 
Zurück