Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

(dll export) Dinamici pozivi funkcija

[es] :: C/C++ programiranje :: (dll export) Dinamici pozivi funkcija

[ Pregleda: 3040 | Odgovora: 14 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

itf
Zagreb

Član broj: 59794
Poruke: 993
*.fsb.hr.



+9 Profil

icon (dll export) Dinamici pozivi funkcija30.05.2005. u 14:41 - pre 229 meseci
Znam da je vec netko otvorio slicnu temu pa se unaprijed ispricavam. Inace, zanima me sljedece:

Recimo da imam sljedecu funkciju:

// funkcija je eksportabilna (navedeno u DLL-u)
double SUMA(double a, double b){
return a + b;
}

Ta funkcija neka je u MojDLL.CPP. Kada compiliram projekt dobijem MojDLL.DLL i sad ga zelim iskoristiti da mogu pozvati tu funkciju negdje u EXE programu. Zanima me DINAMICKI POZIV funkcije. Ne preko statickog LIB-a, vec da funkciju pozivam tek onda kad mi ona treba.

Znam da to treba nekako preko pokazivaca na funkciju, no imam problema sa onim NEARPROC i FARPROC. Kako to tocno ide? Koja je razlika izmedju dllexport, dllimport itd. Unaprijed zahvalan...
 
Odgovor na temu

itf
Zagreb

Član broj: 59794
Poruke: 993
*.fsb.hr.



+9 Profil

icon Re: (dll export) Dinamici pozivi funkcija30.05.2005. u 14:58 - pre 229 meseci
Da, da.. Koristio sam ja funkcije LoadLibrary i GetProcAdress. Sve to uradim i javlja mi da je kriva adresa funkcije kada ju treba pozvati... Naravno nisam ukljucio LIB od dll-a i h datoteke, no da li je moguce koristiti dll a da izbjegnem taj lib i zaglavlja? Moze li pomoci sljedeca linija

export double Suma(double a, double b);

na pocetku programa?
 
Odgovor na temu

Ivan Dimkovic

Administrator
Član broj: 13
Poruke: 16687
*.dip.t-dialin.net.



+7173 Profil

icon Re: (dll export) Dinamici pozivi funkcija30.05.2005. u 15:01 - pre 229 meseci
Bez staticke import-library biblioteke ne mozes automatski linkovati neke funkcije, vec ces morati da se zlopatis sa LoadLibrary/FreeLibrary()

Citat:

Sve to uradim i javlja mi da je kriva adresa funkcije kada ju treba pozvati.


Ovo je neka greska u kodu - postuj ceo kod pa cu pogledati u cemu je prob.

DigiCortex (ex. SpikeFun) - Cortical Neural Network Simulator:
http://www.digicortex.net/node/1 Videos: http://www.digicortex.net/node/17 Gallery: http://www.digicortex.net/node/25
PowerMonkey - Redyce CPU Power Waste and gain performance! - https://github.com/psyq321/PowerMonkey
 
Odgovor na temu

itf
Zagreb

Član broj: 59794
Poruke: 993
*.fsb.hr.



+9 Profil

icon Re: (dll export) Dinamici pozivi funkcija30.05.2005. u 15:08 - pre 229 meseci
Poanta i jest u tome da ja to zelim preko funkcija LoadLibrary i FreeLibrary. Ako vec nesto dijelim sto mi treba samo za compiliranje onda radim samo LIB bez dll-a pa tko hoce nek si radi export svega unutra.

Da li mozes, molim te napisati nekakav primjer gdje se to radi preko pokazivaca na funkcije (GetProcAdress) bez tog LIB-a? Cim vidim taj LIB unutra smuci mi se. Trebam cisti DLL (kao kad npr. koristim resurse iz njega). Hvala
 
Odgovor na temu

blaza
n/a

Član broj: 961
Poruke: 743
*.yu1.net.



+3 Profil

icon Re: (dll export) Dinamici pozivi funkcija30.05.2005. u 16:50 - pre 229 meseci
Tebe zapravo zanima runtime linking. Nadam se da ces sve sto je potrebno naci u ovom primeru: http://www.cs.odu.edu/~wild/windowsNT/Spring99/ddl.htm
O_o
 
Odgovor na temu

itf
Zagreb

Član broj: 59794
Poruke: 993
*.fsb.hr.



+9 Profil

icon Re: (dll export) Dinamici pozivi funkcija30.05.2005. u 16:57 - pre 229 meseci
To je to. Hvala
 
Odgovor na temu

yooyo

Član broj: 4891
Poruke: 1101
*.beotel.net.



Profil

icon Re: (dll export) Dinamici pozivi funkcija31.05.2005. u 00:13 - pre 229 meseci
Ovo je definitivno najlakse:
Code:

DLL:
extern "C" __declspec(dllexport) return_type FuncName( int param )
{
...
}
Prevedi ga kao MyDLL.dll



Napravi MyDLL.h file i ubaci:
Code:

typedef return_type* (__cdecl * PFNFuncName)(int param);


Negde u exe programu:
Code:

#include "MyDLL.h"

PFNFuncName FuncName;
HMODULE h = LoadLibrary("MyDLL.dll");
if (h!=NULL)
{
 FuncName = (PFNFuncName) GetProcAddress(h, "FuncName");
 if (FuncName == NULL) 
 {
  // error
 }
 else
 {
   // pozovi func
   FuncName(23);
 }
}


Ako imas mnogo exportovanih funkcija onda je prilicno maltretiranje da pokupis sve entry points. Postoji jednostavnije resenje. Napravi ciste virtuelnu klasu i exportuj samo jednu funkciju koja vraca pointer na implementaciju te klase. Primer:

Code:

IMyClass.h: (interface-to-my-class)
class IMyClass
{
public:
 IMyClass(){};
 virtual ~IMyClass(){};

 virtual int Metoda1(int p1, int p2) = 0;
 virtual float Metoda2(float p1, int p2) = 0;
...
};

typedef IMyClass* (__cdecl * NewInstanceOfMyClass)(void);
typedef void (__cdecl * DeleteInstanceOfMyClass)(IMyClass* p);


Zatim napravi implementaciju IMyClass:
Code:

MyClass.h:
class MyClass: public IMyClass
{
 public:
 MyClass();
 ~MyClass();

 int Metoda1(int p1, int p2);
 float Metoda2(float p1, int p2);
...
}

MyClass.cpp
extern "C" __declspec(dllexport) IMyClass* NewInstanceOfMyClass(void)
{
  return new MyClass;
}


extern "C" __declspec(dllexport) void DeleteInstanceOfMyClass(IMyClass* p)
{
 if (p!=NULL) delete p;
}



A sada spektakl...
Code:

exe:
main.cpp:
#include "IMyClass.h"
PFNNewInstanceOfMyClass NewInstanceOfMyClass;
PFNDeleteInstanceOfMyClass DeleteInstanceOfMyClass;
// ovde ide LoadLibrary i GetProcAddress(h, "NewInstanceOfMyClass"); i GetProcAddress(h, "DeleteInstanceOfMyClass");

IMyClass* pMyClass = NewInstanceOfMyClass();
pMyClass->Metoda1(23,34); // pozivanje metode u DLL-u;
DeleteInstanceOfMyClass(pMyClass);


Ovde sam ubacio NewInstanceOfMyClass i DeleteInstanceOfMyClass zato sto je prilicno lose da alociras memoriju u dll-u a oslobadjas iz glavnog programa sa delete, jer ako su exe i dll prevedeni sa razlicitim run-time bibliotekama program moze da puca.

Ako jos malo razmislis o ovom metodu vrlo lako mozes da napravis solidan plugin sistem za tvoj program. Npr.. razmisli o tome kako bi izveo da neki dll exportuje vise klasa!

yooyo
 
Odgovor na temu

itf
Zagreb

Član broj: 59794
Poruke: 993
*.fsb.hr.



+9 Profil

icon Re: (dll export) Dinamici pozivi funkcija31.05.2005. u 08:17 - pre 229 meseci
OK. Skuzio sam gotovo sve, ali ne razumijem zasto bas moraju biti u abstraktnoj klasi sve metode ciste virtualne. I ovako se opet mogu adresirati na derivirane klase ako samo imam npr. virtualni destruktor u abstraktnoj klasi (adresiranje preko pokazivaca na abstraktnu klasu...)? Zar ne? Ostale metode mogu biti i overload-ane i u derivacijama abstraktne klase...

SKUZIO SAM! Hvala
 
Odgovor na temu

yooyo

Član broj: 4891
Poruke: 1101
*.nat-pool.bgd.sbb.co.yu.



Profil

icon Re: (dll export) Dinamici pozivi funkcija31.05.2005. u 16:31 - pre 229 meseci
Ako MyClass.h ubacis u .exe projekat, compiler i linker nece naci implementaciju metoda MyClass (jer se to nalazi u dll-u). Koriscenjem pure virtual klase IMyClass ti ces prevariti compiler i linker.

yooyo
 
Odgovor na temu

yooyo

Član broj: 4891
Poruke: 1101
195.252.89.*



Profil

icon Re: (dll export) Dinamici pozivi funkcija12.06.2005. u 09:47 - pre 229 meseci
Zbog havarije ES servera tvoje pitanje i moj odgovor ssu nestali...

Ukratko... Skini sa http://www.dependencywalker.com/ program Dependency Walker. Otvori tvoj dll u njemu i videces spisak exportovanih funkcija. Fnnkcija koju si ti napisao i exportovao je dekorisana sa @ i $ i zato ti GetProcAddress vraca NULL. Pokusaj da je exportujes sa extern "C" {.

yooyo
 
Odgovor na temu

itf
Zagreb

Član broj: 59794
Poruke: 993
*.fsb.hr.



+9 Profil

icon Re: (dll export) Dinamici pozivi funkcija13.06.2005. u 10:01 - pre 229 meseci
Neznam jesi li primjetio ali ako stavim extern "C" tada mi staticki link ne radi, iako to nije slucaj ako isti kod prevedem u Visual .NET-u. Naravno, prethodno sam zamijenio LIB i sve sto je potrebno... Je li mozes ovo probati ispraviti tako da radi na C++ Builder-u pa staviti ovdje? Bio bih ti zahvalan.
 
Odgovor na temu

yooyo

Član broj: 4891
Poruke: 1101
*.pat-pool.bgd.sbb.co.yu.



Profil

icon Re: (dll export) Dinamici pozivi funkcija13.06.2005. u 11:53 - pre 229 meseci
Citat:
itf: Neznam jesi li primjetio ali ako stavim extern "C" tada mi staticki link ne radi, iako to nije slucaj ako isti kod prevedem u Visual .NET-u. Naravno, prethodno sam zamijenio LIB i sve sto je potrebno... Je li mozes ovo probati ispraviti tako da radi na C++ Builder-u pa staviti ovdje? Bio bih ti zahvalan.


Uf... nemam builder. Nije mi jasno zasto staticki link ne radi. Malo sam guglao i nasao sledece:
http://www.rsdn.ru/article/devtools/bcbdll.xml (ako znas ruski)
Izgleda da se MS i Borland nisu dogovoili oko konvencija:
Code:

void foo() postaje:
 
           __stdcall        __cdecl
 MS        _foo@4 (or 0?)   foo
 Borland   foo              _foo


Znaci da bi dobio nedekorisano ime u BCB, moras exportivati funkciju kao __stdcall. Ako koristis taj dll iz MSVC-a obavezno moras naglasiti kompajleru da je to __stdcall tj.
typedef return_type* (__stdcall * PFNFuncName)(int param);


yooyo
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4902
*.ptt.yu.

Jabber: xfiles@elitesecurity.org


+638 Profil

icon Re: (dll export) Dinamici pozivi funkcija13.06.2005. u 12:30 - pre 229 meseci
Pogledaj:
http://www.dahloakland.com/gra...utor/BCBDEV_COM%20Articles.htm
 
Odgovor na temu

itf
Zagreb

Član broj: 59794
Poruke: 993
*.fsb.hr.



+9 Profil

icon Re: (dll export) Dinamici pozivi funkcija13.06.2005. u 12:32 - pre 229 meseci
Budem probao. Ipak, zanimljivo je da kada napravim DLL sa nekom eksportabilnom funkcijom u Visual .NET-u sa obicnim extern "C" tu funkciju bez problema pronadje GetProccAdress i mogu je pokrenuti unutar Borland C++ programa, dok kad taj isti DLL compiliram u Borlandu ne mogu ga pokrenuti ni tu ni tamo..
 
Odgovor na temu

itf
Zagreb

Član broj: 59794
Poruke: 993
*.fsb.hr.



+9 Profil

icon Re: (dll export) Dinamici pozivi funkcija14.06.2005. u 18:30 - pre 229 meseci
SKuzio sam u cemu je rijec. Naime, zbog razlicite konvencije izmedju Borlanda i Microsofta imena funkcija koja je eksporitraju iz DLL-a se nazivaju drukcije u samim modulima (zavisno gdje ste compilirali DLL). Npr.

extern "C" int __declspec(dllexport) Suma(int a, int b);

Ukoliko ovo compilirate u VC++u i u LIB i u DLL ce vam se spremiti originalno ime funkcije ("Suma"). Ukoliko ovo isto compilirate u Borland C++ Builderu u LIB ce vam se spremiti "Suma", a u DLL "_Suma". Borland dodaje underscore prije imena funkcije!

Ovo se moze sprijeciti na dva nacina:

1) Opcija Project/options/advanced compiler
Ovdje je potrebno ukljuciti opciju Standard Call (Calling convention dio).
Sada se svaka funkcija exportira u DLL bez underscore-a, a prototip funkcije sada mora glasiti

extern "C" int __declspec(dllexport) __stdcall Suma(int a, int b);

Ovo morate navesti ako zelite da vam staticki link radi!

2) Ispred imena svake eksportabilne funkcije mozete rucno dodati __stdcall pa ne trebate dirati opcije prevoditelja. Opet, prototip mora glasiti isto kao i gore.

Kada vrsite dinamicko povezivanje tj. kada preko GetProcAdress trazite adresu funkcije sada ne morate navoditi underscore vec originalno ime funkcije.

DAKLE:
------
Ukoliko ste DLL compilirali u VC++u ne trebate se nista brinuti u svezi imena funkcije. Njeno ime je ostalo nepromjenjeno. Ako je DLL napravljen u Borland C++ Builderu tada, bez obzira da li DLL koristite unutar VC++ ili Borland C++ programa UVIJEK MORATE KORISTITI KLJUCNU RIJEC __stdcall. OVO TREBA NAVESTI I KADA SE DEKLARIRA POKAZIVAC NA FUNKCIJU (kod dinamickog linka..).

Staticki link, naravno, zbog konvencije ne radi, pa je u ovom slucaju moguce samo koristiti runtime link kod DLL-ova ovih dviju tvrtki (ako mijesate jedno sa drugim). Eto!




 
Odgovor na temu

[es] :: C/C++ programiranje :: (dll export) Dinamici pozivi funkcija

[ Pregleda: 3040 | Odgovora: 14 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.