[ zrnvltc @ 24.06.2009. 03:56 ] @
Pozdrav
Treba mi primer kako da definisem funciju koja iz
dll-a vraca neki string ( char * Funkcija() )

i kako da iz neke forme ucitam pozovem tu funkciju
i procitam taj pointer na niz karaktera.

Jednostavno nisam nasao na net-u za char*
samo primere za int bool

hvala
[ Mihajlo Cvetanović @ 24.06.2009. 09:48 ] @
Upravo to što si napisao (char * Funkcija()) je jedno moguće rešenje. Naravno, treba ti i ono __declspec(dllextern), a uglavnom se koristi i ono __stdcall, ali ta dva nemaju veze sa baferima, to uvek treba. Šta si ti pokušao, a šta ne valja u tome što si pokušao? Ima nekih drugih problema u mešanju bafera i dll funkcija, ali nije problem da naraviš funkciju.

Ako koristiš char * Funkcija() onda je sledeće pitanje da li bafer kreiraš unutar te funkcije, ili je to samo pokazivač na nešto. Ako kreiraš onda bafer mora i da se obriše u nekom trenutku.

Code:
char * blabla = Funkcija();
...
// Ovde obrisati blabla. Ili ćeš delete[] blabla, ili napraviš funkciju dll-a Delete(blabla). Preporučujem ovo drugo.
[ zrnvltc @ 24.06.2009. 16:45 ] @
jevlja mi u app koja poziva dll
access violation ..... in module "version.dll"
primer koda u dll-u je:
Code:

   DWORD dwSize = GetFileVersionInfoSize(vInfo, &dwDummy);
   char *lpData = new char[dwSize];
   // ........
   // ........
   delete [] lpData;     // >>> ovde puca
[ Mihajlo Cvetanović @ 24.06.2009. 17:03 ] @
Te tri linije na prvi pogled deluju okej, ali premalo si informacija dao. Moraćeš sam da debaguješ korak po korak, ili da ovde pošalješ kompletan a minimalan kod koji ti pravi problem. S druge strane nije mi jasno sledeće: ako u dll-u brišeš bafer lpData šta onda vraća funkcija?

Access violation se javlja kad pristupiš nepristupačnom delu memorije. U tvom slučaju to možda znači da lpData pokazuje na neku nebulozu. Moraćeš sam da utvrdiš kako i otkud. Debagovanje dll-a je isto kao i debagovanje glavne aplikacije, stisni F11 (u Visual Studiu) pred ulazak u funkciju i ulaziš unutra :-)
[ baseQ @ 25.06.2009. 18:57 ] @
Aplikacija koja poziva dll:
U Unit1.h recimo klasi forme:
Code:

private:
   typedef char* __declspec(dllimport) CallFunkcija();   // deklaracija
   CallFunkcija * Poziv;


u Unit21cpp-u:
Code:

   // Prvo ucitavamo Dll.
   HINSTANCE Dll = LoadLibrary(".....putanja\\Moj.dll");
   // Provera da li je Dll ucitan
   if (Dll)
   {
      // Uzimamo adresu funkcije.
      Poziv= (CallFunkcija *)GetProcAddress(Dll, "_Funkcija");
      // e sad Poziv() je u stvari pozivanje funkcije isto kao Funkcija();
      ShowMessage(Poziv());
      // Na kraju oslobadjamo dll.
      FreeLibrary(Dll);
   }
   else
      ShowMessage("error nije ucitan dll bla bla bla..."); 


A u dll-u
Code:

extern "C" __declspec(dllexport) char * Funkcija();    // deklaracija

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
   return 1;
}


i normalno implementacija Funkcije:
Code:

char * Funkcija()
{
   char nekicar[256];
   char *rezultat;
   //....................................
   //....................................
   //....................................
   return rezultat;
}
[ Eurora3D Team @ 25.06.2009. 23:11 ] @
Da nisi uradio nesto ovako?
Code:

char* lpData = new char[dwSize];
// ........
lpData = Funkcija();//iz dlla
// ........
//eventualno
//FreeLibrary(Dll);
delete [] lpData;    

i sta se desava u fn sa rezultat , jel imas new
Mozes da stavis new u Funkcija() , znaci char* rezultat = new char[]
a delete u glavnom programu
npr.
Code:

//dll
char * Funkcija()
{
   char *rezultat = new char[nesto];
   //....................................
   return rezultat;
}
// a ovamo
char* lpData = Funkcija();
//...
if(lpData)
   delete[] lpData;
FreeLibrary(Dll);
[ kiklop74 @ 27.06.2009. 11:25 ] @
Najbezbedniji je pristup koji se u vecini slucajeva koristi u Windows API funkcijama:

Code:

//dll funkcija
extern "C" {
  void __declspec(dllexport) __stdcall getStringValue(char* &buffer, int buffsize) {
     strcpy(buffer,"sample string");
  }
}

// poziv funkcije u aplikaciji
const int bsize = 100;
char pbuff[bsize] = {0};

getStringValue(pbuff,bsize);

std::cout << pbuff << std::endl;



Gornja verzija je vise c++ manir (i svakako preporucen ako koristis c++) a ako bi bio u pitanju cisti C onda bi to izgledalo ovako:

Code:

//dll funkcija
  void __declspec(dllexport) __stdcall getStringValue(char** buffer, int buffsize) {
     strcpy(*buffer,"sample string");
  }

// poziv funkcije u aplikaciji
char pbuff[100];
memset(pbuff,0,100);
char *p=pbuff;
getStringValue(&p,bsize);