Laden...

Interop-Problem?

Erstellt von mupe vor 18 Jahren Letzter Beitrag vor 18 Jahren 1.981 Views
M
mupe Themenstarter:in
8 Beiträge seit 2005
vor 18 Jahren
Interop-Problem?

Hi,

ich binde per Interop eine Anwendung eines anderen Anbieters als COM-Verweis in meine C#-Anwendung ein (die andere Anwendung ist glaube ich C++). Auf die meisten Funktionen und Objekte kann ich erfolgreich zugreifen. Allerdings funktioniert eine Funktion, die ich benötige nicht. Allerdings weiss ich nicht, ob es an mir liegt (bzw. an .NET), oder ob es generell ein Problem der anderen Anwendung ist. Deren Entwickler hat leider auch keine Erklärung und kennt sich nicht mit .NET aus.

Also ich mache folgendes:

Ich habe einen Verweis in meiner Projektmappe auf diese Type Library der anderen Anwendung. (Wie gesagt funktionieren einige Methoden).

Es gibt dort ein Objekt "App".
Dieses Objekt hat eine Methode

BroadcastObj App.get_BrodcastObj(object Value)

Als Parameter "Value" muss man ein eindimensionales Array übergeben, welches Gerätenummern (1, 2, ....) enthält.
Ich hab das folgendermaßen gemacht:

int[] length = new int[1]{2};
int[] bounds = new int[1]{0};
Array appIds = Array.createInstance(typeof(Int32), length, bounds);
appIds.setValue(1, 0);
appIds.setValue(2, 1);
App myApp = new App();
BroadcastObj brObj = myApp.get_BroadcastObj(appIds);

Das Array appIds wird korrekt angelegt und die Werte richtig eingetragen. Ich bekomme auch ein BroadcastObj zurück. Wenn ich dann allerdings eine Methode auf dieses Objekt aufrufe schlägt das fehl (die Methode rufe ich richtig auf, da besteht kein Zweifel). Ich bin mir allerdings nicht sicher, ob dieses Array appIds korrekt in der Methode get_BroadcastObj verarbeitet wird......

Habe mal die Interop-DLL, die mir VS erzeugt hat disassembliert und mit die Methode angeschaut. Das sieht da so aus:

.method public hidebysig newslot specialname virtual
instance class BroadcastObj
marshal( interface)
get_BroadcastObj(object marshal( struct) Value) runtime managed internalcall

Kann mir jemand sagen, ob ich vielleicht mit diesem Array appIds noch etwas machen muss, bevor ich es an die Methode übergebe??? Dann könnte ich mir nämlich sicher sein, obs an mir liegt oder allgemein an der anderen Anwendung.

Hoffe mir kann jemand helfen und vielen Dank schonmal!!

Gruß, Peter

S
8.746 Beiträge seit 2005
vor 18 Jahren

Ich würde den Fehler im Array-Typ vermuten. Offenbar zeichnet das COM-Interface das Array nicht als SAFEARRAY aus. Deswegen kann .NET den Typ nicht erkennen und baut dir ein Objekt.

Zurück zum Code: Alternativ einfach mal nur ein int[] erzeugen und direkt reinstecken, also ohne CreateInstance.

Lass dir doch mal die Signatur der Methode via COMInspektor ausgeben.

M
mupe Themenstarter:in
8 Beiträge seit 2005
vor 18 Jahren

Hm, also die Bounds sind ja auf 0...

Das mit direkt int[] reinstecken hab ich auch schon probiert, funktioniert aber auch nicht. Hab auch schon probiert ein int[] anzulegen und das dann in ein Array zu casten aber das bringt auch nicht wirklich was. Vielleicht liegts ja doch an der Type Library selbst. Es geht dabei um nen Gerätezugriff.

Was ist denn der COMInspector? Hab ich noch nicht gehört.

M
mupe Themenstarter:in
8 Beiträge seit 2005
vor 18 Jahren

Ok, was der COMInspector ist, weiss ich jetzt. Zu dem hab ich jetzt aber auch noch ne Frage.

Ich muss der Methode ja ein Array übergeben. Wie kann ich das im COMInspector machen? Da gibts ja nur das Value-Feld. Hab dann versucht ein Array als Objekt anzulegen, habs aber nicht hinbekommen. Array geht sowieso nicht, da das unter C# ja abstrakt ist. Wie kann ich denn im COM INspector ein Array anlegen?

S
8.746 Beiträge seit 2005
vor 18 Jahren

Der ComInspector zeigt dir einfach nur das COM-Interface an. Du hattest ja den Wrapper-Code gepostet. Nun wäre es spannend auch mal die "Ausgangssituation" zu betrachten. Daher der Verweis auf dem COM-Inspector. Die Frage ist, von welchem Typ das Array im COM-Interface ist. "Object" wäre schlecht, weil schließlich handelt es sich hier um ein Array, und Arrays werden von COM unterstützt. Also sollten sie auch so ausgezeichnet werden.

M
mupe Themenstarter:in
8 Beiträge seit 2005
vor 18 Jahren

Hi,

hab das bzgl. meiner Frage oben hinbekommen. Ich schreib in das Value-Feld einfach

new System.Int32[2]{1,2}

Da bringt er wenigstens keinen Fehler und gibt mir das Broadcast-Objekt zurück, wie in meinem Programm auch. Aber das ursprüngliche Problem besteht weiterhin.

Also im COMInspector zeigt er mir bei Klick auf das Broadcast-Objekt nur an, dass ich ein System.Object übergeben muss..... mehr nicht. Oder kann man da irgendwie noch anders "reinschauen"?

Der Hersteller der Anwendung, auf die ich zugreifen möchte, hat mir versprochen, sich nächste Woche nocheinmal drum zu kümmern. Bis dahin warte ich jetzt mal. Melde mich dann evtl. nochmal.

Danke für die bisherigen Antworten.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Nö, dann ist das einfach so grauenhaft implementiert. Man sollte in COM-Interfaces schon maximal typisieren. Einfach Object zu nehmen und den Nutzer erraten zu lassen, was da rein muss ist kein guter Stil.