Announcement

Collapse
No announcement yet.

An Die Profis, Fehlermeldung bei Funktionsaufruf aus DLL

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • An Die Profis, Fehlermeldung bei Funktionsaufruf aus DLL

    Hallo, ich habe eine DLL geschrieben, in der eine Funktion steht die Farbwerte in HTML Code ändert.
    Die DLL sieht so aus.

    library hexcol;

    uses
    SysUtils,
    Classes,
    Graphics;

    function ColorToHtml(Color: TColor): string; stdcall;
    begin
    Result := '#' + IntToHex( Color and $FF, 2 ) +
    IntToHex( Color shr 8 and $FF, 2 ) +
    IntToHex( Color shr 16 and $FF, 2 );
    end;

    exports
    ColorToHtml;

    begin
    end.

    Ich rufe die DLL und die Funktion so auf.

    function ColorToHtml( Color: TColor ): string; stdcall; external 'hexcol.dll';

    var
    Form1: TForm1;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    flatedit1.text:=colorToHtml(colordialog1.color);
    end;

    Bei click auf den Btn erscheint immer folgende Fehlermeldung

    Invalid Pointeroperation

    Was ist nur falsch?

  • #2
    Hi

    fucntion DLLproc():<b> String</b> ---> <b>= type LongString </b>

    LongString sind dynamisch verwaltete Speicherbereiche. Nun, in der DLL allozierst Du im Speicher der DLL einen solchen String und gibts diesen an den aufrufenden Process, bad

    Entweder Du fügst im DLL project file in der uses Klausel die unit "ShareMem" hinzu, natürlich dann auch in der EXE. oder Du änderts das DLL Design.

    Ich meine ausschließlich der zweite Fall sollte in Frage kommen, weil mit ShareMEM keine anderen NICHT delphi like APP's ohne ShareMem den gleichen fehler wiederholen, bzw. eine VB/VC App gar keine LongStrings kennt.

    also so sollte es aussehen:

    <pre>

    function ColorToHTML(Color: DWord; Text: PChar; MaxLen: DWord): DWord; stdcall;
    var
    S: String;
    begin
    if (MaxLen = 0) or (Text = nil) then Result := 6 + 1 +1 else // '#FFFFFF'
    if Maxlen < 6 + 1 +1 then Result := 0 else
    begin
    S := Format('#%0.2x%0.2x%0.2x', [Color and $FF, Color shr 16 and $FF, Color shr 24 and $FF]);
    StrPLCopy(Text, S)
    result := 7; // ohne Null terminator
    end;
    end;<br>

    // aufruf aus Delphi<br>

    var
    S: String;
    begin
    SetLength(S, 256);
    Setlength(S, ColorToHTML(Color, PChar(S), Length(S)));
    end;<br>

    </pre>

    Wie Du siehst ein ganz anderes design. Die Aufrufende Anwednung sollte IMMER für die Speicherreservierungen und freigeben verantwortlich sein.

    Die Längenangaben resultieren aus 6 zeichen für 'FFFFFF' + 1 zeichen '#' + 1 Zeichen #0 der Null Terminator.

    Einfacher wäre auch:

    <pre>

    rocedure HTMLColor(Color: DWord): DWord;
    asm
    BSWAP EAX
    SHR EAX,8
    end; <br>

    S := '#' + IntToHEX(HTMLColor(Color), 8); <br>

    </pre>

    Gruß hage

    Comment

    Working...
    X