GetProcAddress

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

GetProcAddress

Roland Turcan - RoTurSoft
Hello friends,

I have written a very simple library which contains only two exports.
It is intended to be a bridge between an old application and clipboard
on linux to exchange data.

---------------------------------------------------
library clipbrdgtk;

{$MODE Delphi}

uses
  Classes, Interfaces, Clipbrd;

function clipboard_getastext:PChar; cdecl; export;
begin
  result := PChar (Clipboard.AsText);
end;

PROCEDURE clipboard_setastext (iStr:PChar); cdecl; export;
begin
  Clipboard.AsText := String (iStr);
end;

exports
  clipboard_getastext,
  clipboard_setastext;
begin
  //
end.
-------------------------------------------------------------
when I later try to load it for testing in Lazarus test application I
cannot find the exports:

-------------------------------------------------------------
TYPE TClipboard_GetAsText = FUNCTION:PChar; CDECL;
TYPE TClipboard_SetAsText = PROCEDURE (iStr:PChar); CDECL;

TYPE TClipbrd =CLASS
                      PRIVATE
                        FHandle:HMODULE;
                        FGetAsText:TClipboard_GetAsText;
                        FSetAsText:TClipboard_SetAsText;

                        FUNCTION GetAsText: STRING;
                        PROCEDURE SetAsText(CONST Value: STRING);

                      PUBLIC
                        CONSTRUCTOR Create;
                        DESTRUCTOR Destroy; OVERRIDE;

                        PROPERTY AsText:STRING READ GetAsText WRITE SetAsText;
                      END;

IMPLEMENTATION

USES Classes, SysUtils, Forms, dynlibs;

{ TClipbrd }

CONSTRUCTOR TClipbrd.Create;
var s :string;
BEGIN
  FHandle := 0;

  s := ExtractFilePath (Application.ExeName) + 'clipbrdgtk.so';

  IF FileExists (s) then begin
    FHandle := LoadLibrary (PChar (s));
  END;

  FGetAsText := NIL;
  FSetAsText := NIL;

  IF FHandle <> 0 THEN begin
    FGetAsText := GetProcAddress (FHandle, PChar ('clipboard_getastext'));
    FSetAsText := GetProcAddress (FHandle, PChar ('clipboard_setastext'));
  END;
END;

DESTRUCTOR TClipbrd.Destroy;
BEGIN
  IF FHandle <> 0 THEN begin
    FreeLibrary (FHandle);
  END;

  INHERITED;
END;

FUNCTION TClipbrd.GetAsText: STRING;
BEGIN
  IF Assigned (FGetAsText) THEN begin
    RESULT := FGetAsText;
  END;
END;

PROCEDURE TClipbrd.SetAsText(const Value: STRING);
BEGIN
  IF Assigned (FSetAsText) THEN begin
    FSetAsText (PChar (Value));
  END;
END;
---------------------------------------------------------------

What could be wrong, that it doesn't find the exports and FGetAsText
and FSetAsText stay NIL;

Thanks.

--
Best regards, TRoland
http://www.rotursoft.sk
http://exekutor.rotursoft.sk

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: GetProcAddress

Anthony Walter-3
I am not too sure why GetProcAddress is returning nil, but a few points:

1) you do not need to typecast string literals as PChar

FGetAsText := GetProcAddress (FHandle, 'clipboard_getastext');

2) You really should not return strings as PChar, passing them is fine, but return, nope

result := PChar (Clipboard.AsText);

Why? Because string types are managed and referenced counted. The project returning the string is likely to deallocate the memory returned upon exit (unless you save a copy locally) . A better approach would be to have the caller allocate the memory and return the expected buffer size:

function clipboard_getastext(Buffer: PChar; BufferSize: Integer): Integer;

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal