2009-04-23 6 views
1

Ich habe einen COM-Server mit einem Verfahren für eine ganze Zahl zur Zeit der Rückkehr:Wie kann ich einen benutzerdefinierten Typ (UDT) in einem COM-Server verwenden?

[ 
    object, 
    uuid("..."), 
    dual, 
    helpstring("IMyCOMServer Interface"), 
    pointer_default(unique) 
] 
__interface IMyCOMServer : IDispatch 
{ 
    [id(1), helpstring("method MyQuery")] 
    HRESULT MyQuery([in] BSTR instr, [out,retval] int* outint); 
}; 

Dies kompiliert gut, aber ich würde lieber eine Enumeration zurück: (dieser Code tatsächlich über der Schnittstellendefinition ist)

typedef 
[ 
    uuid("..."), 
    v1_enum, 
    helpstring("Enum") 
] 
enum { 
    value_a, 
    value_b, 
    value_c 
} MyEnum; 

Welche wieder gut von seinem eigenen Recht kompilieren, aber sobald ich die int* zu MyEnum* in der Schnittstelle und Implementierung ändern, erhalte ich Linkerfehler:

[id(1), helpstring("method MyQuery")] 
HRESULT MyQuery([in] BSTR instr, [out,retval] MyEnum* outint); 

error MIDL2025 : syntax error : expecting a type specification near "MyEnum" 

Egal wie ich es mache, ich kann es nicht kompilieren.


Dank Euro Micelli es stellt sich heraus, dass das eigentliche Problem ist, dass meine User Defined Type (die ENUM) wurde es in der generierten IDL-Datei nicht zu machen. Nach Online-Forum-Anfragen zu urteilen, scheint dies ein häufiges Problem zu sein.

Ein Blog-Artikel Star Tech: UDT (User Defined Types) and COM führte mich auf den richtigen Weg. Es scheint, dass ein Workaround bei Verwendung von attributierten ATL benötigt wird.

Zusammengefasst habe ich folgende Änderungen:

Erstellt udt.idl:

import "oaidl.idl"; 
import "ocidl.idl"; 

[ 
    uuid("..."), 
    v1_enum, 
    helpstring("Enum") 
] 
typedef enum MyEnum { 
    value_a, 
    value_b, 
    value_c 
} MyEnum_t; 

[ 
    version(1.0), 
    uuid(...), 
    helpstring(...) 
] 
library MyLibrary 
{ 
    enum MyEnum; 
} 

Hinzugefügt wurde die folgende Zeile vor dem Modul Attribut in der Haupt .cpp-Datei, so dass die obige IDL in die importiert wird generierte Datei:

[importidl("udt.idl")]; 
+0

Können Sie versuchen, enum AA {}; HRESULT MyQuery ([out, retval] enum AA *) 'Ich erinnere mich, dass midl ein sehr' C'-Verhalten hatte (keine automatischen typedefs). – Ismael

+0

Welchen Compiler benutzen Sie? –

+0

@John Dibling: Visual Studio 2005 (aus irgendeinem Grund bin ich nicht auf ein Upgrade auf 2008 gekommen). – Mat

Antwort

1

(Dies ist aus einem tatsächlichen IDL angepasst ist, so dass ich weiß, es funktioniert)

[uuid(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX), v1_enum, helpstring("Enum")] 
enum MyEnum { 
    value_a, 
    value_b, 
    value_c 
} ; 

Plus in der Bibliothek Abschnitt müssen Sie die Enum umfassen auch, oder die ENUM wird nicht an die exportiert werden Typbibliothek:

library MyLib 
{ 
    enum MyEnum; 
... 
}; 
+0

Ahh ... Ich bin mir nicht sicher, dass ich einen Bibliotheksabschnitt habe! – Mat

+0

Rechts. Ich habe einen Bibliotheksabschnitt in meiner generierten .IDL-Datei. Diese Datei enthält die Enumeration überhaupt nicht. Wie bekomme ich die Enum an der richtigen Stelle in der .IDL-Datei? – Mat

+0

Ich weiß es nicht genau; Wird es von Visual Studio generiert? Ich habe die meisten meiner COM/IDL "auf die harte Tour" (VS 6) gemacht, so dass ich mit den neueren Versionen der COM/IDL-Werkzeuge nicht so vertraut bin. Wenn es einmal generiert wird, können Sie es selbst eingeben. Wenn es von VS oder anderen Tools generiert wird, sollte das Tool intelligent genug sein, um zu wissen, dass es den Bibliothekseintrag benötigt. –

1

Dies ist sehr Compiler-abhängig, da Aufzählungen haben keine feste Speichergröße.

Es gibt auch den Kompatibilitätswinkel - wie würden Sie diese Enum in, sagen wir, Visual Basic oder C# darstellen? Der zugrunde liegende Speicher ist so etwas wie eine Ganzzahl, das ist also, was COM erlaubt.

+0

Dies ist nicht C oder C++. Enums in COM-Schnittstellen haben Größen, die durch COM-Regeln definiert sind. VB und C# unterstützen Enums (und sie sind kompatibel mit COM-Enums). Das bedeutet nicht, dass jede Sprache Folgendes erfordert: In VBScript zum Beispiel wird eine Enumeration still auf Integer gemappt. –

1

Sie haben es fast schon, aber der idl-Compiler hat eine etwas strengere Syntax als die cl.exe. Sie müssen den ursprünglichen enum-Namen vor dem enum wie folgt haben.

typedef 
[uuid("..."), v1_enum, helpstring("Enum")] 
enum tagMyEnum 
{ 
    value_a, 
    value_b, 
    value_c 
} MyEnum; 

Wenn Sie Ihre tlb erstellen und registrieren, sollten Skriptsprachen in Scripts und .NET auf Ihre enum zugreifen können.

+0

Datengrößen, die in idl-Dateien für COM-Klassen definiert sind, sind nicht kompilerabhängig, sondern standardisiert. Wenn sie keine Standardgrößen wären, wäre die Interoperabilität der KOM beseitigt und einer der Hauptgründe für die Existenz von COM. – nichow

+0

Ich hatte es vorher mit einem Tag versucht, aber nach dem Lesen von Vorschlägen entfernt. Ich bekomme einen anderen Fehler: Fehler 1 Fehler MIDL2011: ungelöst Typdeklaration: [Parameter 'outenum' von Prozedur 'MyQuery' (Interface 'IMyCOMServer')] Dies ist mit meiner Funktion definiert: HRESULT MyQuery ([in ] BSTR instr, [out, réval] enum tagMyEnum * outenum); – Mat

Verwandte Themen