[Megoldva]Delphi és c++ házasítás.

Fórumok

Sziasztok.

Ketten dolgozunk egy feladaton, ami egy régebben megírt (és alaposan kituningolt) Delphi kódra épül, na eddig nem is volt baj (itt jöttem én a képbe :D ), ugyanis én eddig csak linux alá írtam programot win alá még soha, ergo a delphiről annyit tudok hogy van, és volt linuxos klónja a kylix de a kutyának nem kellet (azt hiszem 3XX-darabot adtak el belőle 1 év alatt).Na szóval a lényeg, egy elég komoly eszköz vezérlését szeretnénk megoldani, de nagyon sok számítást igénylő mestint progi működteti a vezérlést (Ezt írtam én C-ben). Az egyik részét átkódoltuk delphibe, de annyira lassú lett, hogy használhatatlan(Kb a sebesség az 1/2 1/3-ra esett vissza, biztos nem a lehető legjobb mgolás, mert a kollegám grafikai elemeket kódolt eddig, én meg C + egy minimális asm). Na akkor jött az ötlet, hogy elvileg megoldható az, hogy az én kódomat mint dll-t fordítjuk le, és csak a kimeneti paraméterekt adja meg a delphi kódnak, így gyors maradhat (és nekem sem kell a delphivel vacakolni, pláne hogy nem is működik elegendő sebességgel). De ez sehogy nem akar összejönni. Végignéztem egy rakat tutoriált helpet... Azok közül semmivel nem ment. A delphi vagy azt mondja hogy nem léteő dll, vagy azt hogy a menyitott dll-ben nincs ilyen függvény. Nem másolgatok be azokból amit kiőróbáltam mert van vagy 70, de az eredmény ugyanaz, nem tud valaki valami használható ötletet adni? Ja borland developper studio 2006 vagy mi van nekünk.

Azt tudom, hogy az egyik megoldás a C-ben írt dll-re az ez a fajta deklaráció:
extern "C" __declspec(dllexport) int perforationsenzor (int x1, int x2, int y1, int y2, int erzekenyseg)
{
itt jön a kód.
}
Le is fordul szépen, majd hibaüzenetként kiirja, hogy mivel ez egy dll nem tudjuk használni állítsuk be a run/dialogboban, hogy melyik exe használja, na én ezt az exe-t simán elindítom (manuálisan kintről), de a fenti probléma jön elő.

Hozzászólások

delphiben deklarálni kell a függvényedet valahogy így:


function perforationsenzor (x1,x2,y1,y2,erzekenyseg:integer):integer; external 'dllfaljneve.dll';

talán segíthet még a

cdecl

és/vagy a

stdcall

kulcsszó...

--
Falu

A PostgreSql libpq.dll-jében lévő függvényeket így lehet elérni:
Ami telőtte be jkell tölteni!!!!

Definíció


type
  TPQexec          = function(Handle: PPGconn; Query: PChar): PPGresult; cdecl;
  TPQnotifies      = function(Handle: PPGconn): PPGnotify; cdecl;
  TPQfreeNotify    = procedure(Handle: PPGnotify);cdecl;
  TPQsendQuery     = function(Handle: PPGconn; Query: PChar): Integer; cdecl;
  TPQgetResult     = function(Handle: PPGconn): PPGresult; cdecl;
  TPQisBusy        = function(Handle: PPGconn): Integer; cdecl;
  TPQconsumeInput  = function(Handle: PPGconn): Integer; cdecl;
  TPQgetline       = function(Handle: PPGconn; Str: PChar; length: Integer): Integer; cdecl;
  TPQputline       = function(Handle: PPGconn; Str: PChar): Integer; cdecl;
  TPQgetlineAsync  = function(Handle: PPGconn; Buffer: PChar; BufSize: Integer): Integer; cdecl;
  TPQputnbytes     = function(Handle: PPGconn; Buffer: PChar; NBytes: Integer): Integer; cdecl;
  TPQendcopy       = function(Handle: PPGconn): Integer; cdecl;
  TPQfn            = function(Handle: PPGconn; fnid: Integer; result_buf, result_len: PInteger; result_is_int: Integer; args: PPQArgBlock; nargs: Integer): PPGresult; cdecl;
  TPQresultStatus  = function(Result: PPGresult): ExecStatusType; cdecl;
  TPQresultErrorMessage = function(Result: PPGresult): PChar; cdecl;


var
{ ===	in fe-connect.c === }
  PQconnectdb:     TPQconnectdb;
  PQsetdbLogin:    TPQsetdbLogin;
  PQconndefaults:  TPQconndefaults;
  PQfinish:        TPQfinish;
  PQreset:         TPQreset;
  PQrequestCancel: TPQrequestCancel;
  PQdb:            TPQdb;
  PQuser:          TPQuser;
  PQpass:          TPQpass;
  PQhost:          TPQhost;
  PQport:          TPQport;
  PQtty:           TPQtty;
  PQoptions:       TPQoptions;
  PQstatus:        TPQstatus;
  PQerrorMessage:  TPQerrorMessage;
  PQsocket:        TPQsocket;
  PQbackendPID:    TPQbackendPID;
  PQtrace:         TPQtrace;
  PQuntrace:       TPQuntrace;
  PQsetNoticeProcessor: TPQsetNoticeProcessor;

{ === in fe-exec.c === }
  PQexec:          TPQexec;
  PQnotifies:      TPQnotifies;
  PQfreeNotify:    TPQfreeNotify;
  PQsendQuery:     TPQsendQuery;
  PQgetResult:     TPQgetResult;
  PQisBusy:        TPQisBusy;
  PQconsumeInput:  TPQconsumeInput;
  PQgetline:       TPQgetline;
  PQputline:       TPQputline;
  PQgetlineAsync:  TPQgetlineAsync;
  PQputnbytes:     TPQputnbytes;
  PQendcopy:       TPQendcopy;
  PQfn:            TPQfn;
  PQresultStatus:  TPQresultStatus;
  PQresultErrorMessage: TPQresultErrorMessage;
  PQresultErrorField: TPQresultErrorField; //Firmos
  PQntuples:       TPQntuples;
  PQnfields:       TPQnfields;
  PQbinaryTuples:  TPQbinaryTuples;
  PQfname:         TPQfname;
  PQfnumber:       TPQfnumber;
  PQftype:         TPQftype;
  PQfsize:         TPQfsize;
  PQfmod:          TPQfmod;
  PQcmdStatus:     TPQcmdStatus;
  PQoidValue:      TPQoidValue;
  PQoidStatus:     TPQoidStatus;
  PQcmdTuples:     TPQcmdTuples;
  PQgetvalue:      TPQgetvalue;
  PQgetlength:     TPQgetlength;
  PQgetisnull:     TPQgetisnull;
  PQclear:         TPQclear;
  PQmakeEmptyPGresult:  TPQmakeEmptyPGresult;

//FirmOS: New defines
  PQescapeByteaConn:TPQescapeByteaConn;
  PQescapeBytea:TPQescapeBytea;
  PQunescapeBytea:TPQunescapeBytea;
  PQFreemem:TPQFreemem;

{ === in fe-lobj.c === }
  lo_open:         Tlo_open;
  lo_close:        Tlo_close;
  lo_read:         Tlo_read;
  lo_write:        Tlo_write;
  lo_lseek:        Tlo_lseek;
  lo_creat:        Tlo_creat;
  lo_tell:         Tlo_tell;
  lo_unlink:       Tlo_unlink;
  lo_import:       Tlo_import;
  lo_export:       Tlo_export;

A betöltő ős osztály:


function TZNativeLibraryLoader.LoadNativeLibrary: Boolean;
var
  I: Integer;
  Location: string;
  TriedLocations: string;
begin
  Loaded := False;
  Location := '';
  TriedLocations := '';
  if Handle = 0 then
  begin
    for I := 0 to High(FLocations) do
    begin
      Location := FLocations[I];
//      Handle := GetModuleHandle(PChar(Location));
//      if Handle = 0 then
//      begin
{$IFDEF UNIX}
  {$IFDEF FPC}
        Handle := LoadLibrary(PChar(Location));
  {$ELSE}
        Handle := HMODULE(dlopen(PChar(Location), RTLD_GLOBAL));
  {$ENDIF}
{$ELSE}
        Handle := LoadLibrary(PChar(Location));
{$ENDIF}
//      end;
      if Handle <> 0 then
      begin
        Loaded := True;
        Break;
      end;
      if TriedLocations <> '' then
        TriedLocations := TriedLocations + ', ';
      TriedLocations := TriedLocations + Location;
    end;
  end;

  if not Loaded then
    raise Exception.Create(Format(SLibraryNotFound, [TriedLocations]));
  Result := True;
end;

Betöltés


{**
  Loads a library module.
  @return <code>True</code> if library was successfully loaded.
}
function TZPostgreSQLNativeLibraryLoader.Load: Boolean;
begin
  Result := inherited Load;

{ ===	in fe-connect.c === }
  @PQfreemem           := GetAddress('PQfreemem');
  @PQescapeByteaConn   := GetAddress('PQescapeByteaConn');
  @PQescapeBytea       := GetAddress('PQescapeBytea');
  @PQunescapeBytea     := GetAddress('PQunescapeBytea');

  @PQconnectdb    := GetAddress('PQconnectdb');
  @PQsetdbLogin   := GetAddress('PQsetdbLogin');
  @PQconndefaults := GetAddress('PQconndefaults');
  @PQfinish       := GetAddress('PQfinish');
  @PQreset        := GetAddress('PQreset');
  @PQrequestCancel := GetAddress('PQrequestCancel');
  @PQdb           := GetAddress('PQdb');
  @PQuser         := GetAddress('PQuser');
  @PQpass         := GetAddress('PQpass');
  @PQhost         := GetAddress('PQhost');
  @PQport         := GetAddress('PQport');
  @PQtty          := GetAddress('PQtty');
  @PQoptions      := GetAddress('PQoptions');
  @PQstatus       := GetAddress('PQstatus');
  @PQerrorMessage := GetAddress('PQerrorMessage');
  @PQsocket       := GetAddress('PQsocket');
  @PQbackendPID   := GetAddress('PQbackendPID');
  @PQtrace        := GetAddress('PQtrace');
  @PQuntrace      := GetAddress('PQuntrace');
  @PQsetNoticeProcessor := GetAddress('PQsetNoticeProcessor');

{ === in fe-exec.c === }
  @PQexec         := GetAddress('PQexec');
  @PQnotifies     := GetAddress('PQnotifies');
  @PQfreeNotify   := GetAddress('PQfreeNotify');
  @PQsendQuery    := GetAddress('PQsendQuery');
  @PQgetResult    := GetAddress('PQgetResult');
  @PQisBusy       := GetAddress('PQisBusy');
  @PQconsumeInput := GetAddress('PQconsumeInput');
  @PQgetline      := GetAddress('PQgetline');
  @PQputline      := GetAddress('PQputline');
  @PQgetlineAsync := GetAddress('PQgetlineAsync');
  @PQputnbytes    := GetAddress('PQputnbytes');
  @PQendcopy      := GetAddress('PQendcopy');
  @PQfn           := GetAddress('PQfn');
  @PQresultStatus := GetAddress('PQresultStatus');
  @PQresultErrorMessage := GetAddress('PQresultErrorMessage');
  @PQresultErrorField := GetAddress('PQresultErrorField');
  @PQntuples      := GetAddress('PQntuples');
  @PQnfields      := GetAddress('PQnfields');
  @PQbinaryTuples := GetAddress('PQbinaryTuples');
  @PQfname        := GetAddress('PQfname');
  @PQfnumber      := GetAddress('PQfnumber');
  @PQftype        := GetAddress('PQftype');
  @PQfsize        := GetAddress('PQfsize');
  @PQfmod         := GetAddress('PQfmod');
  @PQcmdStatus    := GetAddress('PQcmdStatus');
  @PQoidValue     := GetAddress('PQoidValue');
  @PQoidStatus    := GetAddress('PQoidStatus');
  @PQcmdTuples    := GetAddress('PQcmdTuples');
  @PQgetvalue     := GetAddress('PQgetvalue');
  @PQgetlength    := GetAddress('PQgetlength');
  @PQgetisnull    := GetAddress('PQgetisnull');
  @PQclear        := GetAddress('PQclear');
  @PQmakeEmptyPGresult := GetAddress('PQmakeEmptyPGresult');

{ === in fe-lobj.c === }
  @lo_open        := GetAddress('lo_open');
  @lo_close       := GetAddress('lo_close');
  @lo_read        := GetAddress('lo_read');
  @lo_write       := GetAddress('lo_write');
  @lo_lseek       := GetAddress('lo_lseek');
  @lo_creat       := GetAddress('lo_creat');
  @lo_tell        := GetAddress('lo_tell');
  @lo_unlink      := GetAddress('lo_unlink');
  @lo_import      := GetAddress('lo_import');
  @lo_export      := GetAddress('lo_export');
end;

initialization
{$IFNDEF UNIX}
  LibraryLoader := TZPostgreSQLNativeLibraryLoader.Create(
    [WINDOWS1_DLL_LOCATION
{$IFNDEF STRICT_DLL_LOADING}
    , WINDOWS2_DLL_LOCATION
{$ENDIF}
    ]);
{$ELSE}
  LibraryLoader := TZPostgreSQLNativeLibraryLoader.Create([LINUX1_DLL_LOCATION,LINUX2_DLL_LOCATION]);
{$ENDIF}
finalization
  if Assigned(LibraryLoader) then
    LibraryLoader.Free;
end.

Attila, Perger
-----------------------------------------------------
"Az a szoftver, amelyiket nem fejlesztik, az halott!"

Én erősen ajvaslom, hogy Delphiből használjátok a LoadLibrary("tecuccod.dll"); hívást, illetve a proc-ok bemeléséhez a GetProcAddress() -t.
Ez ezért lesz jó nektek, mert ha a C -s dll-edet újrafordítot, nem kell a Delphi-s programot is újrafordítani.
Hova tudnék felölteni egy kis példa-csomagot? :)