Frage

Ich habe einen Delphi-DLL mit einer Funktion wie folgt definiert:

Funktion SubmitJobStringList (Jobliste: TStringList; var jobno: Integer): Integer;

Ich rufe diese von C #. Wie erkläre ich den ersten Parameter als ein TStringList nicht in C # nicht vorhanden ist. Im Moment habe ich die Erklärung als:

[DllImport("opt7bja.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int SubmitJobStringList(string[] tStringList, ref int jobno);

Aber wenn ich es nenne ich eine Speicherzugriffsverletzung Ausnahme.

Wer weiß, wie man eine TStringList von C # korrekt passieren?

War es hilfreich?

Lösung

Sie werden wahrscheinlich kein Glück mit diesem. Der TStringList ist mehr als nur ein Array, es ist eine ausgewachsene Klasse, und die genauen Details der Implementierung unterscheiden von dem, was möglich ist, mit .NET. Werfen Sie einen Blick auf die Delphi VCL-Quellcode (das heißt, wenn Sie es haben), und versuchen, herauszufinden, ob Sie die Klasse in C # neu erstellen können, und übergeben Sie es mit Hilfe der besten Freundin, die Interop Marshaller. Beachten Sie, dass auch der Delphi-String-Typ aus dem .NET-String-Typ unterschiedlich ist, und weitergeben, ohne die Einweiser zu sagen, was er tun soll, wird er es als ein char-Array übergeben, am wahrscheinlichsten.

Other than that, würde ich vorschlagen, den Delphi-DLL zu ändern. Es ist nie eine gute Sache zu etwas Delphi-spezifisch in einem DLL aussetzen, die von Nicht-Delphi-Clients verwendet werden soll. Machen Sie den Parameter ein Array von PChar und Sie sollten in Ordnung sein.

Andere Tipps

Wenn dies Ihr DLL, würde ich die Funktion neu zu schreiben, anstatt ein Array von Strings zu akzeptieren. Vermeiden Sie vorbei Klassen als DLL-Parameter.

Oder, wenn Sie wirklich ein TStringList aus irgendeinem Grund verwenden möchten, Delphi VCL.Net kann aus jeder .NET-Sprache verwendet werden.

Ein altes Beispiel mit TIniFile: http://cc.codegear.com/Item/22691

Das Beispiel verwendet .NET 1.1 in Delphi 2005 Delphi 2006 und 2007 Unterstützung .Net 2.0.

Wenn Sie nicht über die DLL steuern und sie können oder wollen es nicht ändern, könnten Sie immer Ihren eigenen Delphi-Wrapper in einem separaten DLL mit Parametern schreiben, die mehr Quer Sprache freundlich sind.

wirklich eine Klasse als Parameter einer DLL-Funktion zu haben, ist schlechter Stil.

Ich bin nicht ganz klar den Weg delphi und C # zu verwenden. Es scheint, dass Sie eine Win32-DLL erstellt haben, die Sie von C # anrufen möchten. Offcourse müssen Sie PInvoke dafür verwendet werden.

Ich würde vorschlagen, dass Sie eine .NET-DLL erstellen mit Ihrem Quellcode da eine vollständige Portierung von VCL zur Verfügung steht. Ich kann weiter ausarbeiten, wenn Sie wünschen ....

In der Theorie Du könnte etwas tun, wie dies durch Zeiger (Gießen sie als C # IntPtr-Typ) anstelle von stark typisierten Objektreferenzen (oder sie vielleicht in einer anderen Art Verpackung um zu vermeiden, deklarieren unsichere Blöcke), aber der wesentliche Fang ist dies: die Delphi-Laufzeit der Mechanismus für die Zuweisung und das Aufheben von Zuweisungen Speicher für die Objekte sein muß. Zu diesem Zweck Sie Funktionen in Ihrer Delphi-kompilierte DLL deklarieren müssen, die die Konstruktoren und Destruktoren für die TStringList Klasse aufrufen, müssen Sie sicherstellen, dass Ihre Delphi DLL die ShareMem Einheit verwendet, und Sie müssen die Verantwortung übernehmen für die Erhöhung und Erniedrigen des Referenzzähler für Ihre Delphi Ansistrings, bevor sie verlassen die DLL und nachdem sie es betreten, vorzugsweise auch als Funktionen von Delphi DLL exportiert.

Kurz gesagt, es ist ein Los der Arbeit, da Sie zwei Speichermanager in demselben Prozess jonglieren müssen (die .NET CLR und Delphi Verteilern), und Sie müssen beide verwalten den Speicher manuell und "Narr" der Delphi-Speicher-Manager und die Laufzeit. Gibt es einen bestimmten Grund, warum Sie zu diesem Setup gebunden sind? Könnten Sie das Problem beschreiben Sie auf einer höheren Ebene zu lösen versuchen?

Wie Hemant Jangid sagte, sollten Sie leicht in der Lage sein, dies zu tun, indem Sie den Code als .NET-DLL kompiliert und dann zu dieser Versammlung in Ihrem c # -Projekt verweist.

Natürlich können Sie nur sein, dies zu tun, wenn die Version von Delphi Sie haben Delphi.NET hat.

Ich weiß nicht viel über C #, sondern eine Technik, die ich für den Transport von Stringlisten über Kontexte verwenden wird, um die .text Eigenschaft mit der Liste einen String erhalten darstellt, dann diese Eigenschaft zuweisen auf den „anderen Seite“.

Es ist in der Regel einfacher, eine Schnur über die Mauer zu bekommen, dass es ein vollständiges geblasenes Objekt ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top