AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

How to - string in DLL

Ein Thema von WojTec · begonnen am 16. Jun 2011 · letzter Beitrag vom 22. Jun 2011
Antwort Antwort
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#1

Re: How to - string in DLL

  Alt 19. Jun 2011, 16:49
I tested @Luckies code and it working in example, but don't work in this case:

Delphi-Quellcode:
function func1(s: PChar; Buffer: PChar; lenBuffer: Integer): Integer; external 'StringDLL.dll';

var
  Buffer: array [0..MAX_PATH] of Char;
  BufferSize: DWORD;
begin
  BufferSize := High(Buffer);
  func1('bar', Buffer, BufferSize);
  ShowMessage(Buffer);
end;
Raises AV. Windows functions working, this one not. Why?

Geändert von WojTec (19. Jun 2011 um 17:02 Uhr) Grund: Added static linked function
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.948 Beiträge
 
Delphi 12 Athens
 
#2

AW: How to - string in DLL

  Alt 19. Jun 2011, 17:57
One inportant issue first:
Always use PWideChar or PAnsiChar in DLL interfaces. Otherwise it depends on the Delphi version and what PChar means in it whether your program works or not...

Regarding your problem:
I don't see an error handling (you ignore the return value). And where does the exception occur? Inside the DLL function?

And could you please post the source of the function inside the DLL too?
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#3

Re: How to - string in DLL

  Alt 19. Jun 2011, 19:14
Code (function from @Luckie article).

Delphi-Quellcode:
library StringDLL;

uses
  SysUtils;

function func1(s: PWideChar; Buffer: PWideChar; lenBuffer: Integer): Integer; stdcall;
var
  foo: String;
begin
  foo := 'foo'+ s;
  if Assigned(Buffer) then
    StrLCopy(Buffer, PWideChar(foo), lenBuffer);
  Result := Length(foo);
end;

exports
  func1;

begin
end.

function func1(s: PWideChar; Buffer: PWideChar; lenBuffer: Integer): Integer; external 'StringDLL.dll';

procedure TForm1.Button1Click(Sender: TObject);
var
  Buffer: array [0..MAX_PATH] of Char;
  BufferSize: DWORD;
begin
  BufferSize := High(Buffer);
  func1('bar', Buffer, BufferSize);
  ShowMessage(Buffer);
end;
Windows functions I'm using in the sam way, exception in DLL.

Original example is working:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
  hLib: THandle;
  s: String;
  foo1: function(s: PChar; Buffer: PChar; lenBuffer: Integer): Integer; stdcall;
  len: Integer;
  Buffer: PChar;
begin
  Buffer := nil;
  hLib := LoadLibrary('StringDLL.dll');
  if hLib = 0 then
  begin
    Str(GetLastError, s);
    ListBox1.Items.Add('LE: ' + s);
    exit;
  end;
  Str(hLib, s);
  ListBox1.Items.Add('hlib: ' + s);
  @foo1 := GetProcAddress(hLib, 'func1');
  if (not Assigned(foo1)) then
  begin
    Str(GetLastError, s);
    ListBox1.Items.Add('AE: ' + s);
    exit;
  end;
  Str(Integer(@foo1), s);
  ListBox1.Items.Add('@func1: ' + s);
  len := foo1('', nil, 0);
  Str(len, s);
  ListBox1.Items.Add('len: ' + s);
  try
    GetMem(Buffer, len + 1);
    len := foo1('', Buffer, len + 1);
    Str(len, s);
    ListBox1.Items.Add(String(Buffer)+ ' [' + s + ']');
  finally
    FreeMem(Buffer);
  end;
end;
I prefer 1st method (as in WinAPI). Why it don't working?

Geändert von WojTec (19. Jun 2011 um 19:18 Uhr) Grund: PWideChar
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.948 Beiträge
 
Delphi 12 Athens
 
#4

AW: Re: How to - string in DLL

  Alt 19. Jun 2011, 19:45
Delphi-Quellcode:
  foo := 'foo'+ s;
  if Assigned(Buffer) then
    StrLCopy(Buffer, PWideChar(foo), lenBuffer);
You try to copy lenBuffer Bytes from foo, but it does not have so many Bytes.

By the way: I prefer the way most of the API functions work:
First I ask for the buffer size needed, then I reserve enough memory and ask for the data itself.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#5

Re: How to - string in DLL

  Alt 19. Jun 2011, 20:11
Delphi-Quellcode:
library StringDLL;

uses
  SysUtils;

function Foonction(Data: PWideChar; Buffer: PWideChar; lenBuffer: Cardinal): Cardinal; stdcall;
var
  S: string;
begin
  S := 'foo' + Data;

  if Assigned(Buffer) then
    StrLCopy(Buffer, PWideChar(S), lenBuffer)
  ;

  Result := Length(S);
end;

exports
  Foonction;

begin
end.
Dynamic - working:

Delphi-Quellcode:
var
  hLib: THandle;
  func1: function(s: PChar; Buffer: PChar; lenBuffer: Integer): Integer; stdcall;
  len: Integer;
  Buffer: PChar;
begin
  Buffer := nil;
  hLib := LoadLibrary('StringDLL.dll');
  if hLib <> 0 then
  begin
    ListBox1.Items.Add('hlib: ' + IntToStr(hLib));
    @func1 := GetProcAddress(hLib, 'Foonction');
    if Assigned(func1) then
    begin
      ListBox1.Items.Add('@func1: ' + IntToStr(Integer(@func1)));
      len := func1('bar', nil, 0);
      ListBox1.Items.Add('len: ' + IntToStr(len));
      try
        GetMem(Buffer, len + 1);
        len := func1('bar', Buffer, len + 1);
        ListBox1.Items.Add(String(Buffer)+ ' [' + IntToStr(len) + ']');
      finally
        FreeMem(Buffer);
      end;
    end;
  end;
end;
Static - don't working:

Delphi-Quellcode:
function Foonction(Data: PWideChar; Buffer: PWideChar; lenBuffer: Cardinal): Cardinal; external 'StringDLL.dll';

var
  Buffer: PWideChar;
  BufferSize: DWORD;
begin
  BufferSize := Foonction('bar', nil, 0);
  ShowMessage(IntToStr(BufferSize));

  GetMem(Buffer, BufferSize + 1);
  try
    Foonction('bar', Buffer, BufferSize + 1);
    ShowMessage(Buffer);
  finally
    FreeMem(Buffer);
  end;
end;
Now I have identical sizes, what's wrong?
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

AW: How to - string in DLL

  Alt 19. Jun 2011, 20:18
Does Length return the count of characters or the count of Bytes? If it returns the count of characters you have to multiply it by 2 if it's a WideChar.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.948 Beiträge
 
Delphi 12 Athens
 
#7

AW: How to - string in DLL

  Alt 19. Jun 2011, 21:25
What about this:
Delphi-Quellcode:
function Foonction(Data: PWideChar; Buffer: PWideChar; lenBuffer: Cardinal): Cardinal; external 'StringDLL.dll';

var
  Buffer: string;
  BufferSize: DWORD;
begin
  BufferSize := Foonction('bar', nil, 0);
  if BufferSize > 0 then
  begin
    SetLength(Buffer, BufferSize);
    Foonction('bar', PWideChar(Buffer), BufferSize);
  end
  else
    Buffer := '';
  ShowMessage(Buffer);
end;
But it would be better if you made lenBuffer a variable parameter. This way you can return the buffer size and a return value.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#8

Re: How to - string in DLL

  Alt 20. Jun 2011, 10:48
Oh gosh, I forgot add stdcall before external in app. Ah Now working! Thanks

Also a few of you told that better is using WideChar. I tried this:

Delphi-Quellcode:
// In DLL

function FooncUni(Data: WideString): WideString; stdcall;
var
  S: string;
begin
  S := 'foo' + Data;

  Result := S;
end;

// In app:

function FooncUni(Data: WideString): WideString; stdcall external 'StringDLL.dll';

Caption := FooncUni('bar'); // Caption is 'foobar'
and working without any problems (as normal string type in EXE, that's cool ). But early @himitsu told:

How to use the functions, they are required to something in this case?

Also another think: to use Ansii or Unicode I have to write 2 functions with PWideChar and PAnsiChar parameters? Or one lets say Unocode version and second to convert Unicode Buffer to Ansi - how? And WideString - it is always Unicode?
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.948 Beiträge
 
Delphi 12 Athens
 
#9

AW: How to - string in DLL

  Alt 20. Jun 2011, 15:53
Also another think: to use Ansii or Unicode I have to write 2 functions with PWideChar and PAnsiChar parameters? Or one lets say Unocode version and second to convert Unicode Buffer to Ansi - how?
Well, for the version with PAnsiChar you append an A, and for PWideChar a W.
For example the API has ShellExecuteA and ShellExecuteW. Delphi itself maps ShellExecute to ShellExecuteA (Delphi 1 - 2007) or to ShellExecuteW (Delphi 2009+). So you don't see that you call one of the other functions.

And WideString - it is always Unicode?
Yes it is.

I myself do not want to use it because it relies on OLE and the operating system. That's why it is much slower. Of course this doesn't matter unless you call such a method often.

For COM WideStrings are very useful (I also used them to interact with .NET libraries with exported native functions), but for other purposes I do not use them.

But it is your decision, both ways work.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
WojTec

Registriert seit: 17. Mai 2007
482 Beiträge
 
Delphi XE6 Professional
 
#10

Re: How to - string in DLL

  Alt 20. Jun 2011, 17:54
Thanks guys, you helped me so much!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz