Προς το περιεχόμενο

Φορτωμα dll απο αλλο φακελο win32 c++


Evgenios1

Προτεινόμενες αναρτήσεις

Δημοσ.

Εστω ο,τι εχουμε ενα προγραμμα το οποιο ειναι στο "C:\myapp\app.exe", και αυτο εχει καποια dll. Πως μπορω να βαλω τα dll σε αλλο φακελο, πχ "C:\myapp\dlls\somedll.dll" και οχι εκει που ειναι το προγραμαμ.

 

Το IDE ειναι ms vc++ 08

Δημοσ.

τότε θα πρέπει το λειτουργικό να ξέρει που να βρεί το dll (π.χ. να είναι στο path).

 

Τα lib που βάζεις στο VC object/library modules, απλά κάνει το loadlibrary για σένα και έχει και entry points για τις συναρτήσεις του dll. Κατα την εκτέλεση του exe σου, αν τα windows δεν βρούν το dll γκρινιάζουν.

Δημοσ.

Απο αρκετο ψαξιμο και πειραματισμο, καταλαβα οτι η LoadLibrary etc.. ειναι για c functions/variables :-( .Αν θελω να κανω export μια class, πως θα κανω? Μεχρι τωρα εχω κανει το εξης.

>[color="#008000"][i]// capp.cpp : Defines the entry point for the console application.[/i][/color]
[color="#008000"][i]//[/i][/color]
[color="#0000ff"]#include[/color] [color="#a31515"]"stdafx.h"[/color]
[color="#0000ff"]#pragma[/color] comment(lib,[color="#a31515"]"E:\\mathdll.lib"[/color])
[color="#0000ff"]#define[/color] DLLPATH L[color="#a31515"]"E:\\mathdll.dll"[/color]
[color="#0000ff"][b]class[/b][/color] __declspec(dllimport) Math
{
[color="#0000ff"][b]public[/b][/color]:
[color="#8000ff"]int[/color] Add([color="#8000ff"]int[/color] a,[color="#8000ff"]int[/color] ;
};
[color="#0000ff"][b]typedef[/b][/color] [color="#8000ff"]int[/color]		  (__cdecl *Pow)([color="#8000ff"]int[/color],[color="#8000ff"]int[/color]);
[color="#0000ff"][b]typedef[/b][/color] HINSTANCE (__cdecl *GetMathCls)([color="#0000ff"][b]void[/b][/color]);

[color="#8000ff"]int[/color] WaitForExit(HINSTANCE lib);


[color="#8000ff"]int[/color] _tmain([color="#8000ff"]int[/color] argc, _TCHAR* argv[])
{
HINSTANCE hLib = LoadLibrary(DLLPATH);
[color="#0000ff"][b]if[/b][/color](hLib==NULL)
{
	printf([color="#a31515"]"apotyxia fortoshs %lstoy dll\n"[/color]);
	[color="#0000ff"][b]return[/b][/color] WaitForExit(NULL);
}

   Pow pPow = (Pow)GetProcAddress(hLib,[color="#a31515"]"Pow"[/color]);
[color="#0000ff"][b]if[/b][/color](pPow == NULL)
{
	printf([color="#a31515"]"apotyxia fortoshs ths synarthshs\n"[/color]);
	[color="#0000ff"][b]return[/b][/color] WaitForExit(hLib);
}
printf([color="#a31515"]"h Pow fortose:2^4=%d\n"[/color],pPow([color="#ff8000"]2[/color],[color="#ff8000"]4[/color]));

[color="#0000ff"][b]void[/b][/color] *pMath = ([color="#0000ff"][b]void[/b][/color]*) [color="#0000ff"][b]new[/b][/color] [color="#8000ff"]char[/color][[color="#0000ff"][b]sizeof[/b][/color](Math)];
GetMathCls getMath = (GetMathCls)GetProcAddress(hLib,[color="#a31515"]"GetMathCls"[/color]);
HINSTANCE hMathCls = getMath();
[color="#0000ff"][b]if[/b][/color](hMathCls==NULL)
{
	printf([color="#a31515"]"den einai dynath h fortosh ths Math_Cls"[/color]);
	WaitForExit(hLib);
}
memcpy(pMath,hMathCls,[color="#0000ff"][b]sizeof[/b][/color](Math));
Math *newMath = (Math*)pMath;
   
[color="#008000"][i]//printf("4+4=%d\n",newMath->Add(4,4));[/i][/color]
[color="#0000ff"][b]delete[/b][/color][] pMath;



[color="#0000ff"][b]return[/b][/color] WaitForExit(hLib);
}
[color="#8000ff"]int[/color] WaitForExit(HINSTANCE lib)
{
FreeLibrary(lib);
getchar();
[color="#0000ff"][b]return[/b][/color] [color="#ff8000"]0[/color];
}

Η γκρινια του compiler ειναι για αυτο εδω το κομματι

>printf("4+4=%d\n",[color="Red"]newMath->Add(4,4)[/color]);

μου λεει οτι δε βρισκει τα symbols :-(... Εγω του λεω οτι ειναι εδω

>#pragma comment(lib,"E:\\mathdll.lib")

αλλα αυτος επιμενει οτι δε τα βρισκει....:-(

 

το api ειναι αυτο.

 

>[color="#0000ff"]#pragma[/color] once
[color="#0000ff"]#ifdef[/color] MATH_EXPORT
[color="#0000ff"]#define[/color] MATH_API __declspec(dllexport)
[color="#0000ff"]#else[/color]
[color="#0000ff"]#define[/color] MATH_API __declspec(dllimport)
[color="#0000ff"]#endif[/color]

[color="#0000ff"][b]class[/b][/color]  MATH_API Math_cls
{
[color="#0000ff"][b]public[/b][/color]:

[color="#8000ff"]int[/color] Add([color="#8000ff"]int[/color] a,[color="#8000ff"]int[/color] ;

};
[color="#0000ff"][b]extern[/b][/color] [color="#a31515"]"C"[/color] MATH_API [color="#8000ff"]int[/color] Pow([color="#8000ff"]int[/color] base,[color="#8000ff"]int[/color] exp);
[color="#0000ff"][b]extern[/b][/color] [color="#a31515"]"C"[/color] MATH_API HINSTANCE GetMathCls([color="#0000ff"][b]void[/b][/color]);

 

Δημοσ.

κλικ.......

 

Δες το κομμάτι με τα interfaces/abstruct classes. Θα χρησιμοποιήσεις το naming convertion που έχει χρησιμοποιηθεί στο dll φυσικά απο τον compiler

Δημοσ.

Αυτο ηταν? ενα virtual ? thx τωρα ειναι μια χαρα! :-D

 

>// capp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#pragma comment(lib,"E:\\mathdll.lib")
#define DLLPATH L"E:\\mathdll.dll"
class __declspec(dllimport) Math
{
public:
virtual int Add(int a,int =0;
};
typedef int		  (__cdecl *Pow)(int,int);
typedef Math* (__cdecl *GetMathCls)(void);

int WaitForExit(HINSTANCE lib);


int _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE hLib = LoadLibrary(DLLPATH);
if(hLib==NULL)
{
	printf("apotyxia fortoshs %lstoy dll\n");
	return WaitForExit(NULL);
}

   Pow pPow = (Pow)GetProcAddress(hLib,"Pow");
if(pPow == NULL)
{
	printf("apotyxia fortoshs ths synarthshs\n");
	return WaitForExit(hLib);
}
printf("h Pow fortose:2^4=%d\n",pPow(2,4));
GetMathCls getMath = (GetMathCls)GetProcAddress(hLib,"GetMathCls");
Math *pMath = getMath();
if(pMath==NULL)
{
	printf("den einai dynath h fortosh ths Math_Cls");
	WaitForExit(hLib);
}
printf("4+4=%d\n",pMath->Add(4,4));
delete[] pMath;



return WaitForExit(hLib);
}
int WaitForExit(HINSTANCE lib)
{
FreeLibrary(lib);
getchar();
return 0;
}

 

Δημοσ.
κλικ.......

 

Δες το κομμάτι με τα interfaces/abstruct classes. Θα χρησιμοποιήσεις το naming convertion που έχει χρησιμοποιηθεί στο dll φυσικά απο τον compiler

 

Διαβασα ολο το αρθρο και τωρα καταλαβα αυτη τη προταση σου... Δηλαδη ελεος, τι παλουκι ειναι αυτο!!

 

Δηλαδη απο αυτο το dll

post-103086-129063031677_thumb.jpg

μπορεις να χρησιμοποιησεις μονο το Pow και GetMathCls? Ενω για τα αλλα πρεπει να εχεις τον ιδιο compiler που εχω και εγω?

Δηλαδη το DirectX SDK πχ ειναι μονο για ms vc++ ? :confused:

Δημοσ.
Διαβασα ολο το αρθρο και τωρα καταλαβα αυτη τη προταση σου... Δηλαδη ελεος, τι παλουκι ειναι αυτο!!

...

Αν έχεις άλλο compiler ίσως είναι μπέρδεμα. Λέω ισως γιατί τα ονόματα είναι αρκετά τυποποιημένα εδω και αρκετό καιρό (ευτυχώς:mrgreen:) και δεν πρέπει να διαφέρουν απο compiler και compiler. Τα ονόματα των συναρτησεων στη C++ όπως τα φτιάχνει o compiler έχουν μέσα τους και το class που ανήκουν, τον τύπο (virtual,...) και τις παραμέτρους της συνάρτησης γι'αυτο υπήρχε το μπέρδεμα με το να τις βρείς/καλέσεις.

 

Όταν αρχικά σχεδίασαν τα DLL είχαν σκεφτεί μόνο τα extern "C" σαν entry points. Μετά προσαρμόστηκε η C++ πάνω τους.

Δημοσ.
Δηλαδη το DirectX SDK πχ ειναι μονο για ms vc++ ? :confused:

 

Όχι, μπορείς να το χρησιμοποιείς και από άλλους compilers όπως για παράδειγμα τον CG C++ Builder και αυτό διότι το DirectX βασίζεται στην τεχνολογία COM η οποία εκ πρώτης όψεως μοιάζει με τα C++ classes (τα περίφημα Interfaces) από την άλλη πλευρά όμως πρόκειται για C οπότε τα functions των DLLs είναι ουσιαστικά extern “C” με την κλήση των οποίων παίρνεις τα Interfaces objects και κάνεις την δουλεία σου. Γενικά το COM είναι σχεδιασμένο έτσι ώστε να παίζει "εύκολα" με κάθε γλώσσα προγραμματισμού (language agnostic) ή τουλάχιστον αυτός είναι ένας βασικός στόχος αυτής της τεχνολογίας.

 

Υ.Γ.

Το θέμα όσον αφορά το DirectX και άλλους compilers είναι συνήθως στο πόσο συμβατοί είναι οι τελευταίοι με τα headers (.h) που παρέχει η Microsoft, δηλαδή πόσο συμβατοί είναι με τον VC++ compiler της MS ώστε να επεξεργαστούν σωστά τις δηλώσεις των header και να ολοκληρωθεί το compiling, εκεί λοιπόν μπορεί να υπάρξουν προβλήματα. Tο ίδιο μπορεί να συμβεί με την μορφή κάποιων casts στο source (.cpp) που μπορεί να διαφέρουν από compiler σε compiler και εκεί επίσης θέλει λίγο ψάξιμο και υπομονή :-\

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...