Einzelnen Beitrag anzeigen

Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
655 Beiträge
 
Delphi 12 Athens
 
#1

Delphi-ActiveX-DLL in VB.Net: Problem mit Strings

  Alt 3. Apr 2012, 15:51
Einen schönen Nachmittag in die Runde,

ich begebe mich gleich in drei Bereichen auf für mich neues Gebiet und stoße da vielleicht etwas an meine Grenzen: Testen von XE2, Entwicklung einer ActiveX-DLL und Arbeiten mit Visual Studio. Wobei ich letzteres vor allem nutzen wollte, um zu testen, ob das, was ich in Delphi an DLL erstellt habe, auch unter anderen Systemen funktioniert.

Das Ziel wird es letztlich sein, einem Kunden eine DLL zur Verfügung zu stellen, über die er von einem Server Daten in sein eigenes System importieren kann. Hier geht es aber jetzt erst einmal nur darum, ein paar ganz einfache Tests ans Laufen zu bekommen.

Ein Vorteil, statt einer "einfachen DLL" eine ActiveX-DLL zu nehmen, sei es unter anderem, dass man einfacher mit Strings arbeiten kann, so dachte ich. Doch genau daran scheitert es: Wenn ich aus VB.Net heraus eine Funktion aufrufe, die einen String zurückgibt, erhalte ich (in VB) eine Zugriffsverletzung.

Folgendes habe ich gemacht:

In Delphi ein neues Projekt erstellt, und zwar eine "ActiveX-DLL". Dort habe ich dann ein "Automatisierungsobjekt" hinzugefügt und diesem wiederum zwei Methoden verpasst. Die DLL "myteststr32.dll" exportiert dann die Typbibliothek "TestStr32" mit dem Interface "IStringOps" und dort den beiden Methoden "ReverseStr" und "CountStrLength".

"ReverseStr" soll einen String übergeben bekommen und diesen in umgekehrter Reihenfolge zurückgeben. "CountStrLength" soll einfach nur die Länge des Strings zurückgeben (spannend, oder? )

So sieht die Implementierung in Delphi aus:

Delphi-Quellcode:
unit teststr32_impl;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  ComObj, ActiveX, TestStr32_TLB, StdVcl;

type
  TStringOps = class(TAutoObject, IStringOps)
  protected
    function CountStrLength(const aInStr: WideString): SYSINT; stdcall;
    function ReverseStr(const aInStr: WideString): WideString; stdcall;
  end;

implementation

uses ComServ;

function TStringOps.CountStrLength(const aInStr: WideString): SYSINT;
begin
  Result:=Length(aInStr);
end;

function TStringOps.ReverseStr(const aInStr: WideString): WideString;

var i: integer;

begin
  Result:='';
  for I := length(aInStr) downto 1 do
    Result:=Result+aInStr[i];
end;

initialization
  TAutoObjectFactory.Create(ComServer, TStringOps, Class_StringOps,
    ciMultiInstance, tmApartment);
end.
Wenn ich die DLL, die beim Compilieren entsteht, registriere und dann in einem neuen Delphi-Projekt diese einbinde, dann klappt das auch alles ganz ausgezeichnet. Das Wichtige soll es aber sein, dass auch außerhalb der Delphi-Welt alles funktioniert.

Weil ich gerade eh ein Win8-Testsystem mit Visual Studio 2011 Beta hier habe, dachte ich mir, dass sich das doch gut für einen Test eignen würde.

Also: Neues WinForms-Projekt erstellt, zwei Buttons, ein Editfeld ("Textbox") und ein Label für die Ausgabe auf das Formular gezogen. Die DLL lässt sich hier mindestens so leicht wie in Delphi importieren (Projekt->Verweis hinzufügen) und kann dann im Code verwendet werden. Im Formular soll man nun in die Textbox einen beliebigen Text eingeben können. Bei dem Druck auf den einen Button soll angezeigt werden, wie lang der Text ist, beim anderen Button soll der umgedrehte Text ausgegeben werden. So sieht der Code aus:

Code:
Public Class Form1
    Private Sub ButtonReverse_Click(sender As Object, e As EventArgs) Handles ButtonReverse.Click
        Dim testStr As TestStr32.StringOps
        testStr = New TestStr32.StringOps

        LabelResult.Text = testStr.ReverseStr(TextBoxInput.Text)
    End Sub

    Private Sub ButtonLength_Click(sender As Object, e As EventArgs) Handles ButtonLength.Click
        Dim testStr As TestStr32.StringOps
        testStr = New TestStr32.StringOps

        LabelResult.Text = testStr.CountStrLength(TextBoxInput.Text).ToString
    End Sub
End Class
Funktioniert nur nicht. Also: ButtonLength_Click, also die Ausgabe, wie lang der String ist, klappt tadellos, aber die Ausgabe des umgedrehten Textes führt beim Aufruf der Funktion zu einer Zugriffsverletzung, also genau in der Zeile:
Code:
LabelResult.Text = testStr.ReverseStr(TextBoxInput.Text)
Ideen? Mache ich in VB irgendwas falsch oder in Delphi oder machen Strings hier generell wieder mal Probleme?

Hilfe!

Bis denn
Bommel
  Mit Zitat antworten Zitat