Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Colevariant / Variant

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] > 2 < [ 3 ]
010
29.07.2003, 12:37 Uhr
ao

(Operator)



Zitat:
0xdeadbeef postete
Ein gut programmierter Server bietet für sowas eine C++-Schnittstelle mit einer Template ...


Leider falsch. So was ist vielleicht gut programmiert, aber kein Server, weil es keine Clients gibt, die ihn benutzen können.

Zitat:

Es geht hier um Schnittstellendefiniton, nicht um das, was der Server intern macht.

Eben. Und man kann nur das definieren, was im "Wortschatz" von Automation vorgesehen ist. Und C++-Templates gehören nun mal nicht dazu.

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
29.07.2003, 12:54 Uhr
0xdeadbeef
Gott
(Operator)


Aber im Wortschatz von C++. In den templates kann dann meinetwegen sowas drinstehen wie

C++:
template <class _T> do_something(_T bla) {
    call_automation_procedure(COleVariant(bla));
}


und dann nur in Spezialfällen eine besondere Implementation, aber Typsicherheit sollte m.E. erst so spät wie möglich aufgegeben werden.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
29.07.2003, 13:41 Uhr
0xdeadbeef
Gott
(Operator)


Abgesehen davon müsste es eigentlich möglich sein, den Server so zu implementieren, dass er weiß, was er will. Es macht für mich jedenfalls keinen erkennbaren Sinn, auf der Clientseite alles zu einem Variant zusammenzubasteln, nur, um es nachher auf der Serverseite wieder auseinanderzupfriemeln. Da kann man genausogut (oder vielmehr, besser) gleich den richtigen Datentyp schicken.

Das ist natürlich ein bisschen Designaufwand, und frißt vielleicht zu Anfang mehr Zeit. Dafür kann man nachher aber auch vernünftig damit arbeiten, und muss nicht solche Dinge wie

C++:
void getRangeFromExcel(IDispatch *dsp) {
    m_vtMeinVariantWert = dsp->Invoke(_T("Value"));
}


ziehen. Das mag für Visual Basic OK sein, weil die Sprache eh nur interpretiert wird und mangels Compilezeit alles zur Laufzeit passieren muss , aber sowas als C++-Interface anzubieten ist unter aller Sau.

P.S: Ich weiß, dass das Beispiel ein bisschen überzogen ist, aber ich denke, der Punkt wird klar.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 29.07.2003 um 13:42 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
013
29.07.2003, 13:46 Uhr
ao

(Operator)



Zitat:
0xdeadbeef postete
Aber im Wortschatz von C++. In den templates kann dann meinetwegen sowas drinstehen wie

C++:
template <class _T> do_something(_T bla) {
    call_automation_procedure(COleVariant(bla));
}


und dann nur in Spezialfällen eine besondere Implementation, aber Typsicherheit sollte m.E. erst so spät wie möglich aufgegeben werden.


Ich glaube, wir reden aneinander vorbei. Niemand programmiert eine OLE-Automation-Schnittstelle, wenn nur innerhalb eines Programms zwei C++-Klassen miteinander reden sollen.

Aber wenn jemand zum Beispiel Werte aus einer Excel-Tabelle auslesen will, dann muß er nicht fopen ("bla.xls") machen und das Format selber auseinanderfiddeln. Dann benutzt er die OLE-Automation-Schnittstelle, die Excel mitbringt. Dazu braucht er keine Template-Header, sondern nur das Exe-Programm selber. Die Programmierschnittstelle ist in standardisiertem Binärformat in der Exe-Datei enthalten. Excel dient als Automation-Server.

Der Client, der die Tabellenwerte abholt und irgendwie verarbeitet, muß auch nicht in C++ geschrieben sein. Wenn die Aufgabe einfach ist, gehts in VisualBasic oder in einer Skriptsprache wahrscheinlich viel schneller.

Leider können Basic und Javascript mit C++-Templates nichts anfangen. Man braucht einen anderen Weg, um Daten zwischen Client und Server zu übertragen. Und das geht entweder typsicher über Parameter, die typsicher in OLE-Automation-Methoden eingebaut sind, oder "halb typsicher" über VARIANT-Parameter, die eine weiche Typkennung (vt) mitbringen.

Man muß von Fall zu Fall entscheiden, ob es günstiger ist, die Daten typsicher oder in VARIANTs zu transportieren. Aber diese Entscheidung muß aus Sicht des Clients, nicht aus Sicht des Servers fallen, denn der Server wird nur einmal geschrieben, aber wenn er gut ist, dann wird er von vielen Client-Programmierern benutzt. Und die gängigen Client-Sprachen haben eine Laufzeitumgebung, die dem Programmierer das Hantieren mit VARIANTs abnimmt, so daß das dort viel einfacher ist als in C++.

Das Client-Server-Konzept sieht so aus: Der Server-Programmierer macht die Drecksarbeit, aber er macht sie einmal und so gründlich, daß die Client-Programmierer sie ein für allemal nicht mehr machen müssen.

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
29.07.2003, 13:52 Uhr
0xdeadbeef
Gott
(Operator)


Wenn es so wäre, dass der Server sauber programmiert wäre und der Client sich nicht mehr die Hände schmutzig machen müsste, dann bekäme ich keine Variants vom Server und müsste nicht solchen Siff-Code in mein Programm schreiben:

C++:
if     (v.vt & VT_R8 ) dVal = v.dblVal;
else if(v.vt & VT_R4 ) dVal = v.fltVal;
else if(v.vt & VT_I4 ) dVal = v.lVal;
else if(v.vt & VT_I2 ) dVal = v.iVal;
else if(v.vt & VT_UI1) dVal = v.bVal;
else throw CIllegalArgumentException(v);


Das ist übrigens eine Stelle (leicht abgeändert), an der ich Daten aus Excel ziehen will. Und das ist in der dritten Wrapper-Schicht, also in der Implementation eines Wrappers um einen Wrapper um einen Wrapper um ein Dispatch-Interface. Das Excel-Developers-Kit, oder was immer das IRange-Interface bietet, hab ich hier leider nicht zur Hand, sonst wären es nur zwei Wrapper-Schichten, aber grausam ist das immer noch.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 29.07.2003 um 13:54 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
015
29.07.2003, 14:15 Uhr
ao

(Operator)



Zitat:
0xdeadbeef postete
Es macht für mich jedenfalls keinen erkennbaren Sinn, auf der Clientseite alles zu einem Variant zusammenzubasteln, nur, um es nachher auf der Serverseite wieder auseinanderzupfriemeln.


Wenn das alles ist, hast du recht. Aber manchmal hat man eine Funktion, die mit verschiedenen Argumenttypen sinnvoll gefüttert werden kann. Und dann machen Variants durchaus Sinn.

Zitat:

Das ist natürlich ein bisschen Designaufwand, und frißt vielleicht zu Anfang mehr Zeit.


Manchmal ist es auch ein Freiheitsgrad, den man behalten will. Wenn ein Server in der Welt ist, kann man ihn nicht zurückholen, um noch mal schnell was am Interface zu ändern. Also baut man vorsichtshalber ein paar VARIANT-Parameter ein, über die man später noch weitere Dinge schieben kann, wenn sich zeigt, daß man was vergessen hatte.

Zitat:

Dafür kann man nachher aber auch vernünftig damit arbeiten, und muss nicht solche Dinge wie

C++:
void getRangeFromExcel(IDispatch *dsp) {
    m_vtMeinVariantWert = dsp->Invoke(_T("Value"));
}


ziehen. Das mag für Visual Basic OK sein, weil die Sprache eh nur interpretiert wird


Stimmt nicht. VB erzeugt lauffähige Kompilate.

Zitat:
und mangels Compilezeit alles zur Laufzeit passieren muss , aber sowas als C++-Interface anzubieten ist unter aller Sau.


In VB (und in den meisten anderen Client-Sprachen) sieht so was auch eleganter aus, da sieht man nur noch

Code:
MeinWert = Range.Value


oder so ähnlich, und um den Rest kümmert sich das Runtime-System. Noch mal: OLE-Automation wurde nicht erfunden, damit die C++-Programmierer es schön haben. Sondern damit (fast) beliebige Programme sich miteinander unterhalten können, egal in welcher Sprache sie geschrieben wurden. C++ ist hier nicht das Maß der Dinge.

Und Invoke mußt du auch in C++ nicht aufrufen, es sei denn, es gibt kein duales Interface. Aber das ist echt selten.

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
016
29.07.2003, 14:30 Uhr
0xdeadbeef
Gott
(Operator)


Für die Office-Interfaces darfste extra blechen, und zwar nicht zu knapp. Ansonsten möchte ich anmerken, dass CORBA, das im wesentlichen nach demselben Prinzip funktioniert wie COM, meines Wissens wunderbar ohne Variants auskommt.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
017
29.07.2003, 14:37 Uhr
ao

(Operator)



Zitat:
0xdeadbeef postete

C++:
if     (v.vt & VT_R8 ) dVal = v.dblVal;
else if(v.vt & VT_R4 ) dVal = v.fltVal;
else if(v.vt & VT_I4 ) dVal = v.lVal;
else if(v.vt & VT_I2 ) dVal = v.iVal;
else if(v.vt & VT_UI1) dVal = v.bVal;
else throw CIllegalArgumentException(v);




Selber schuld. Nimm ::VariantChangeType() oder COleVariant::ChangeType() oder CComVariant::ChangeVarType().

Zitat:

... Das Excel-Developers-Kit ...

... hab ich noch nie benutzt, darum kann ich da nichts zu sagen. Das Durchhangeln durch die Programmiermodelle ist in C++ fummeliger als in Basic, das stimmt. Aber dein Code (Invoke, v.vt) läßt vermuten, daß du einiges noch nicht gefunden hast. Schon mal CComPtr oder CComQIPtr gesehen?

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
018
29.07.2003, 14:39 Uhr
ao

(Operator)



Zitat:
0xdeadbeef postete
Für die Office-Interfaces darfste extra blechen, und zwar nicht zu knapp. Ansonsten möchte ich anmerken, dass CORBA, das im wesentlichen nach demselben Prinzip funktioniert wie COM, meines Wissens wunderbar ohne Variants auskommt.

Wie geht das denn in Corba?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
019
29.07.2003, 14:48 Uhr
0xdeadbeef
Gott
(Operator)



Zitat:
ao postete
Selber schuld. Nimm ::VariantChangeType() oder COleVariant::ChangeType() oder CComVariant::ChangeVarType().


Danke für den Tip.


Zitat:
ao postete
Aber dein Code (Invoke, v.vt) läßt vermuten, daß du einiges noch nicht gefunden hast. Schon mal CComPtr oder CComQIPtr gesehen?


Gesehen ja, bringt mir aber nicht viel, solange ich kein IRange-Interface habe.


Zitat:
ao postete
Wie geht das denn in Corba?


Über objektorientierte Konzepte wie Polymorphismus. Ist ein bisschen zu kompliziert, um es in zwei Sätzen zu erklären.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] > 2 < [ 3 ]     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: