[ Plamenko @ 11.03.2002. 12:43 ] @
Zeleo bih da iz dll-a koji je napravljen u C++ Builder-u(Version 5) izvucem neke metode ali mi bas ne ide?!? Takodje covek koji je napravio taj dll ne moze da koristi moj dll (napravljen u Delphi-u). Naravno on opusteno radi sa svojim dll-om bez ikakvih problema i ja sa svojim. Zna li neko u cemu je tajna? koristili smo standardne tipove tako da neverujem da je u tome problem. Naime u C++ dll-u postoji funkcija koja ne prima nikakve parametre a vraca string (AnsiString).
[ Riste Pejov @ 11.03.2002. 15:45 ] @
Ne bi trebalo biti problema ukoliko su procedure definirane kao stdcall
i string parametre koje ulaze ili izlaze budu pchar (pointer to null terminated string)
[ Plamenko @ 11.03.2002. 17:44 ] @
Uspeo sam da izvucem funkciju iz C++ dll-a ali sad imam drugi problem:
funkcija je uspesno odradjena, vraca vrednost koju treba ali se ceo program zapuca nakon zavrsetka rada sa dll-om. Dll izgleda ovako:

#include <vcl.h>
#pragma hdrstop

#include "DLLUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TDLLForm *DLLForm;
//---------------------------------------------------------------------------
__fastcall TDLLForm::TDLLForm(TComponent* Owner)
: TForm(Owner)
{
name = "No chosen name.";
}
//---------------------------------------------------------------------------
AnsiString __fastcall TDLLForm::GetName()
{
return name;
}
//---------------------------------------------------------------------------

void __fastcall TDLLForm::FirstNameButtonClick(TObject *Sender)
{
name = "Ime.";
Close();
}
//---------------------------------------------------------------------------
void __fastcall TDLLForm::LastNameButtonClick(TObject *Sender)
{
name = "Prezime.";
Close();
}
//---------------------------------------------------------------------------
//Exported function
AnsiString ChooseName()
{
AnsiString name;
TDLLForm* DLLForm = new TDLLForm(NULL);
DLLForm->ShowModal();
name = DLLForm->GetName();
delete DLLForm;
return name;
}
//---------------------------------------------------------------------------

i kazem funkcija vrati odgovarajucu vrednost koja nazalost nikad ne stigne da se prikaze na Delphi formi (neki EditBox ili Label ) zato sto se program zapuca?!?
[ Riste Pejov @ 11.03.2002. 17:57 ] @
a da postujes delphi kod iz kojeg zoves dll ?
i nadam se da si video ono sto sam pisao .... ali ipak da ponovim stdcall !!!
stdcall dll-ovi mogu da se koriste iz VB,Delphi,C++ itn ...
a mozes i explicitno pozvati destruktor objekta pre nego obrises pointer
( jest da se destruktori sami pozivaju ali tako ces biti siguran da to ne zapucava program )
[ Plamenko @ 12.03.2002. 19:22 ] @
Greska je bila u tome sto dll funkcija napisana u C++-u nije bila deklarisana kao stdcall. Kada je to prepravljeno sve radi kako treba. Ali...

Evo u cemu je stvar:

u Delphi-ju deklaracija izgleda otprilike ovako:
Function ChooseName():String;stdcall;external 'cdll.dll' name 'ChooseName';

i onda poziv otprilike:

procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption:=ChooseName();
end;

Nakon klika na dugme Button1 pojavljuje se formica iz dll-a i u zavisnosti od toga sta je odabrano dodeljuje label-u odgovarajuci string. Problem se sad javlja kad se dugme pritisne vise puta. Naime nakon izbora u dll formi, ta forma nestaje ,a label u delphi formi dobije svoj string ali ako to pokusam nekoliko puta da uradim program se zapuca (pa nekad cak i ceo racunar, plavi ekran itd.) ,a javlja poruke tipa: out of memory,illegal operation,problem sa kenel32.dll,problem sa vcl50.dll... sve zavisi. Mislim da su u pitanju objekti koji se kreiraju pozivom dll-a (forma i tri dugmeta kao i lokalne promenljive),a ostaju na steku po zavrsetku rada sa dll-om i niko ih ne unisti (samo pretpostavka), stoga bi mogao malo da pojasnis onaj deo tvoje poruke o pozivanju destruktora i eksplicitnom unistavanju objekata. I ej, hvala na pomoci :).
[ Riste Pejov @ 12.03.2002. 23:36 ] @
Jos nigde nisam video kako exportujes funkciju iz Cbuildera,
i najverovatnije to je exportuje kao cdecl a ne stdcall,

kao sto si rekao prvi put se funkcija izvrsi a drugi put nece.
to je zato sto ti je pozivas kao stdcall, a funkcija je najverovatnije exportirana
nesto slicno ovome:
Code:

extern "C" AnsiString __declspec (dllexport) ChooseName();

kod stdcall rutina sama skida parametre sa steka, a kod cdecl proces koji poziva funkciju mora iscistiti stek. bas zbog toga prvi put sve prodje a drug put popuca.

Umesto ansistring declariraj funkcije kao char*, a kad iz zoves pozovi ih ovako:
Code:

Function ChooseName():Pchar;cdecl;external 'cdll.dll' name 'ChooseName'; 

Ali ako si vec promenio export da bude stdcall onda si zavrsio pola posla,
samo ti jos treba da parametri koje vracaju ili primaju budu char* a iz delphija da ih zoves kao PChar :) To sto sam pomenu o pozivanju destruktora ne treba ti,
posto kad obrises pointer C++ sam pozove destruktor, ali ako toliko hoces mozes i to da probas ovako:
.....
DLLForm->Free(); // pozovi destruktor objekta
delete DLLForm; // pa onda obrisi pointer
...

Ali naci ces puno textova gde pise da to NE VALJA ! da kad pozoves delete na pointer, on sam izvrsi destruktor objekta

pozdrav
[ Plamenko @ 13.03.2002. 10:19 ] @
Funkcija se iz Builder-a exportuje kao stdcall (napomenuo sam da je to bila greska ali je ispravljeno) ,a i poziva se u Delphiju kao stdcall. Medjutim nisam probao da odradim celu stvar sa Pchar tipom. Probacu pa cu javiti.
[ boyan @ 14.03.2002. 02:08 ] @
Riste, ja sam onaj "covek koji je napravio C++ dll" (citiram Plamenka)
Hvala na savetu za __stdcall, odn. cdecl...
Kazi mi samo zasto insistiras na PChar tj. char* umesto AnsiString-a, odn. zar ne
moze da ostane AnsiString ali da ukljucim u CBuilder dll projekat i memmgr.lib
(bar tako pise pri startovanju DllWizard-a)?
Jeste da bi tada i onaj ko koristi dll to isto morao da uradi, ali me interesuju mogucnosti...
[ Riste Pejov @ 14.03.2002. 13:05 ] @
Mozda bi to moglo da radi sa borlandovim memory menagerom, ali nikad nisam
probao to uraditi iz CB5 i prebaciti u delphi i kako bi to radilo pojma nemam, hteo sam, samo da profunkcionira stvar sa BCB dll importa u delphi, a kombinacija sa char* i Pchar je SIGURNO resenje. Ukoliko uspete da to proradite sa AnsiString, onda postujte tips&tricks

Keep on the good work