[ FranjoZG @ 11.12.2020. 10:20 ] @
Pokušavam napraviti DLL u kom mi je ispis. Problem je slanje parametra koji je string (mora biti string).

DLL radim sa XE 10.1 - ne može u D2007 jer mi treba FastReport
Program radim sa D2007 - ne može u XE 10.1 jer je prevelik da bi ga se prepisivalo

DLL:
Code:

...
procedure Ispis_Rjesenja_DLL(BrRjesenja: PChar); stdcall; export;
var IniP: string;
    ti: TIniFile;
    sn, s: string;
begin
   sn := string(BrRjesenja); // pokušao sam razne kombinacije: StrPas(); 
end;
...
   exports Ispis_Rjesenja_DLL;
begin
end.



Program:
Code:

...
  procedure Ispis_Rjesenja_DLL(BrRjesenja: PChar); stdcall; external 'IspiRjesenja_DLL';
...

Procedure Ipis;
begin
   Ispis_rjesenja_DLL(Pchar(BrRjesenja);
end;


U dll-u sn bude nečitljiv string - kineski znakovi.

Kada sam radio test program, ali u XE 10.1 sve radi kako treba, kada proceduru pozivam iz D2007 - problem sa parametrom "BrRjesenja".
[ savkic @ 11.12.2020. 12:13 ] @
> Kada sam radio test program, ali u XE 10.1 sve radi kako treba, kada proceduru pozivam iz D2007 - problem sa parametrom "BrRjesenja".

U XE10.1 string = UnicodeString a u D2007 string = AnsiString.
Tri resenja, deklarisi i prosledjuj PWideChar/PAnsiChar/PUTF8Char.
[ FranjoZG @ 14.12.2020. 10:21 ] @
Pokušao sam varijante koje su mi pale na pamet, nisam uspio riješiti problem.

Može li tko (ako mu se da) napisati dio procedure u D2007 koji poziva proceduru iz DLL-a pisanog u XE 10.1 sa stringom kao parametrom, tj. što i kako napraviti da u proceduri u XE 10.1 dobijem string.
Što god da sam probao, u proceduri (u XE 10.1) mi je string neprepoznatljiv.
[ tkaranovic @ 14.12.2020. 11:14 ] @

Ja sam pisao za Delphi 2007 i XE 7. Nisam probao kako bui radilo sa XE 10.x ali bi trebalo da radi.

Mdjutim poisao za PRO Delphije pa me interesuje da li su to PRO ili ARC delphiji?
[ FranjoZG @ 14.12.2020. 17:18 ] @
Riješio sam malo zaobilazno, ne izgleda mi eleganto, ali radi... ako tko zna bolje rješenje, bilo bi mi drago.
u programu (D2007), poziv procedure;
Code:

procedure TMainFrm.Ispisrjeenja21Click(Sender: TObject);
var s: AnsiString;
    i: integer;
    pba: array of byte;
begin
      
    s := dm.RjesenjaQryBROJ.AsString;
    SetLength(pba, Length(s)+1);
    
    for i := 1 to Length(s) do
       pba[i-1] := Ord(s[i]);
       
   Ispis_Rjesenja_DLL(@pba[0]);
end;


Procedura (XE 10.1):
Code:

procedure Ispis_Rjesenja_DLL(BrRjesenja: PByte); stdcall; export;
var i: integer;
     sBrRjesenja: string;
     pb: pByte;
begin
   i := 0;
   sBrRjesenja := '';
   pb := BrRjesenja;
   
   while (i < 20) and (pb^ <> 0) do begin // "I" je tu samo da mi ne ode u beskonaču petlju
     sBrRjesenja := sBrRjesenja + chr(pb^);
     inc(pb);
     inc(i);
   end;
   ...
end;
[ tkaranovic @ 14.12.2020. 19:52 ] @
Trebalo je da ugrade kontrolu kvalitetka koda.
Onda bi prvo proverila kvaltet.
Ako nije dovljno dobar rekla bi bljak ovo necu da kompajliram :)

Posto ne postoji kontrola kvaliteta,
ako dodas jos jedan paramtar/argument imaces duzinu stringa.
[ savkic @ 15.12.2020. 00:25 ] @
Komplikujes...

Tu je glavni problem kodna strana pa zavisno do toga dva nacina:

Ako ti je tekst u Ascii (ili ti nije bitno) kodnoj strani onda je najlakse:

Code:

procedure IspisRjesenja(const AStrValue: PAnsiChar); stdcall; export;
var
   Temp: AnsiString;
   TempStr: string;
begin
   Temp := AStrValue;
   TempStr := Temp; 
   DoSomething(TempStr); // Ovo moze sve skraceno ali dajem primer
end;

U D2007 to pozivas sa IspisResenja(PAnsiChar(MojNekiString));

Ako ti je kodna strana bitna (npr nasa latinica)

procedure IspisRjesenja(const AStrValue: PWideChar); stdcall; export;
var
   TempStr: string;
begin
   TempStr := AStrValue;
   DoSomething(TempStr); 
end;

U D2007 to ide ovako:

var
  MojString: string; // Tj. AnsiString
  Temp: WideString;
begin
  Temp := AnsiStringToUnicode(1250, MojString);
  IspisRjesenja(Temp);
end;

function AnsiStringToUnicode(const ACodePage: Integer; const ASource: string): WideString;
begin
  Result := AnsiStringToUnicode(ACodePage, PChar(ASource), Length(ASource));
end;

function AnsiStringToUnicode(const ACodePage: Integer; ASource: PChar; const ALen: Integer): WideString;
var
  Len: Integer;
begin
  // Ako je ALen -1 onda pretpostavljamo da je ASource null terminated string u suprotnom konvertujemo ALen karaktera
  if ALen = -1 then
    Len := StrLen(ASource)
  else
    Len := ALen;

  SetLength(Result, Len);
  AnsiStringToUnicode(ACodePage, PChar(ASource), Len, PWideChar(Result));
end;

function AnsiStringToUnicode(const ACodePage: Integer; ASource: PChar; const ALen: Integer; ADest: PWideChar): PWideChar;
begin
  if ALen > 0 then
    ADest[MultiByteToWideChar(ACodePage, 0, ASource, ALen, ADest, ALen)] := #0;

  Result := ADest;
end;