Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: VCL (C++ Builder) ::  Mehrdeutigkeit 'ULONG_PTR' und 'Wmplib_tlb::ULONG_PTR'     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
JoeAl
Unregistrierter




Beitrag JoeAl Unregistrierter 01:49:46 11.06.2017   Titel:   Mehrdeutigkeit 'ULONG_PTR' und 'Wmplib_tlb::ULONG_PTR'            Zitieren

Hallo,

ich habe den WindowsMediaPlayer als ActiveX Komponente hinzugefügt, zudem FTP und HTTP.

Ich will eine Datei auf dem Server auslesen, darin enthalten sind Links zu Videos, die dann über den MediaPlayer innerhalb der Form abgespielt werden.

BCB 2009, Projektbedingungen Strict

Die Liste der Fehler ist lang, erster Punkt:
winsock2.h
ULONG_PTR Key;

Kann mir jemand helfen ?


#include <iostream.h>
#include <cstdlib>
#include <iostream>
#include <stdio.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "WMPLib_OCX"
#pragma link "ResizeKit"
#pragma link "IdBaseComponent"
#pragma link "IdComponent"
#pragma link "IdExplicitTLSClientServerBase"
#pragma link "IdFTP"
#pragma link "IdHTTP"
#pragma link "IdTCPClient"
#pragma link "IdTCPConnection"
#pragma resource "*.dfm"




[BCC32 Fehler] winsock2.h(1094): E2015 Mehrdeutigkeit zwischen 'ULONG_PTR' und 'Wmplib_tlb::ULONG_PTR'
[BCC32 Fehler] iosfwd(254): E2238 Bezeichner 'char_traits<wchar_t>::int_type' mehrfach deklariert
...
SeppJ
Global Moderator

Benutzerprofil
Anmeldungsdatum: 10.06.2008
Beiträge: 27916
Beitrag SeppJ Global Moderator 12:19:33 12.06.2017   Titel:              Zitieren

Nach ein bisschen wühlen durch hauptsächlich chinesische Google-Ergebnisse, würde ich als Lösung eine Änderung der Include-Reihenfolge vorschlagen, so dass WMPLib_OCX als letztes kommt. Wohl gesagt: Include. Wie Pragma Link und Include miteinander wechselwirken kann ich dir aber leider nicht sagen, weil ich nie Pragma Link benutzte. Das musst du selber heraus finden, was das jeweils für die Reihenfolge bedeutet.

_________________
Korrekte Rechtschreibung und Grammatik sind das sprachliche Äquivalent zu einer Dusche und gepflegter Kleidung.
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 2695
Beitrag DocShoe Mitglied 12:28:57 12.06.2017   Titel:              Zitieren

Das Problem ist die völlig bescheuerte Delphi-Unart, alles in namespaces zu verpacken und die im gleichen Header am Ende per using-Direktive wieder in scope zu bringen.

Der wmplib_tlib.hpp Header sieht vermutlich so oder so ähnlich aus:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef Wmplib_tlbH
#define Wmplib_tlbH
 
namespace Wmplib_tlb
{
   ...
   typedef ... ULONG_PTR ...
};

#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_WMPLIB_TLIB)

using namespace Wmplib_tlb
#endif


Wenn das so aussieht hast du Glück und kannst das Verhalten steuern, indem du nicht direkt die wmplib_tlb.hpp inkludierst, sondern eine eigene Header Datei erstellst, die vor dem Inkludieren das Symbol NO_USING_NAMESPACE_WMPLIB_TLIB definiert:

C++:
#ifndef MYWMPLIBH
#define MYWMPLIBH

#define NO_USING_NAMESPACE_WMPLIB_TLIB

#include <wmplib_tlb.hpp>

#endif


Alternativ kannst du auch in den Projektoptionen das Symbol NO_USING_NAMESPACE_WMPLIB_TLIB definieren.

Wenn der #if !defined(...) Block nicht existiert, musst du die using namespace Direktive aus der .hpp Datei entfernen und möglicherweise mehr Quelltext korrigieren, bis es wieder kompiliert.

_________________
Die fünf häufigsten Anzeichen für Faulheit:
1.


Zuletzt bearbeitet von DocShoe am 12:29:31 12.06.2017, insgesamt 1-mal bearbeitet
audacia
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.02.2005
Beiträge: 4722
Beitrag audacia Mitglied 13:05:11 12.06.2017   Titel:              Zitieren

DocShoe schrieb:
Das Problem ist die völlig bescheuerte Delphi-Unart, alles in namespaces zu verpacken und die im gleichen Header am Ende per using-Direktive wieder in scope zu bringen.
Daß alle verwendeten Namespaces standardmäßig geöffnet werden, ist weder unüblich noch verwerflich, sondern halt eine Designentscheidung; C# macht das auch so.

Trotzdem gibt es hier einige Probleme:

  • Delphi übergeht mehrdeutige Symbolreferenzen stillschweigend und nimmt einfach das zuletzt definierte Symbol, was zur Folge hat, daß es auf die Reihenfolge der Module in der uses-Liste ankommt. Das halte ich für einen Designfehler.

  • der Formdesigner erzeugt Code ohne explizite Namespace-Bezüge. (In Delphi führt das zusammen mit dem the last definition wins-"Feature" zu dem folgenden sehr gängigen Pattern: wenn du nur für deine Formklasse eine Komponente subclassen willst, kannst du einfach vor die Form-Definition ein type TButton = class(StdCtrls.TButton) ... end; setzen; der Formdesigner braucht so nicht zu wissen, daß du eine neue Komponente definiert hast.)

  • weil Delphi keine Headerdateien lesen kann, gibt es Delphi-Units für die meisten Headerdateien aus dem Windows-SDK. Da wiederum C++Builder die SDK-Header verwenden kann, muß in den entsprechenden Delphi-Units durch spezielle Direktiven dafür gesorgt werden, daß die im dort definierten Typen nicht in die automatisch generierte Headerdatei exportiert werden (und daß Mangling und Objektlayout kompatibel sind), sondern daß stattdessen Verweise auf die SDK-Typen erzeugt werden. Deshalb ist das using namespace für diese Header i.d.R. kein Problem.

    Das Problem entsteht hier, weil die Typbibliothek als Delphi-Unit importiert wurde, und weil aus Gründen der Abwärtskompatibilität dann eben dieses using namespace in den Header eingefügt wird wie für jedes andere Delphi-Unit. Weil das Unit aber automatisch erzeugt wurde, hat natürlich niemand darauf achten können, daß keine Symbolkonflikte mit SDK-Typen entstehen.


Es gibt also zwei Möglichkeiten:

1. du importierst die Typbibliothek als C++-Unit. Der TLB-Importer sollte eine überschaubare Menge an SDK-Typen erkennen (wie hoffentlich auch ULONG_PTR) und für diese keine Definition erzeugen.

2. oder du definierst in den Projektoptionen das Symbol NO_USING_NAMESPACE_WMPLIB_TLIB, wie DocShoe vorschlug.

_________________
"Hey, it compiles! Ship it!"
C++Builder Pages · Typsichere Format-Strings
Th69
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.03.2008
Beiträge: 4568
Beitrag Th69 Mitglied 14:26:14 12.06.2017   Titel:              Zitieren

audacia schrieb:
C# macht das auch so.

Nein, man muß auch in C# explizit
C#:
using System; // oder anderer Namespace

schreiben.
audacia
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.02.2005
Beiträge: 4722
Beitrag audacia Mitglied 14:54:23 12.06.2017   Titel:              Zitieren

Th69 schrieb:
Nein, man muß auch in C# explizit
C#:
using System; // oder anderer Namespace

schreiben.

Na eben, das ist doch genau wie in Delphi:

Delphi:
uses
  SysUtils;

_________________
"Hey, it compiles! Ship it!"
C++Builder Pages · Typsichere Format-Strings
Th69
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.03.2008
Beiträge: 4568
Beitrag Th69 Mitglied 17:20:12 12.06.2017   Titel:              Zitieren

Aber du hast geschrieben:
audacia schrieb:
Daß alle verwendeten Namespaces standardmäßig geöffnet werden, ist weder unüblich noch verwerflich, ...

Hier ging es doch um den von Delphi erzeugten C++-Code, d.h. durch das Einbinden der Header wird automatisch der Namespace geöffnet (wenn man nicht die Defines definiert hat). Und in C# ist ja ein Namespace und dessen Typen (Klassen, Interfaces, ...) alleine durch dessen Einbinden in das Projekt bekannt. Das "using ..." ist dann nur noch dafür da, damit man den Namespace nicht explizit immer hinschreiben muß, d.h. auch ohne kann man auf die enthaltenen Typen zugreifen.
In Delphi muß man aber explizit die "uses"-Klausel hinschreiben, damit das Modul im Source bekannt gemacht wird (quasi "#include" und "using" in einem) -> also im Unterschied zu C#!
audacia
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.02.2005
Beiträge: 4722
Beitrag audacia Mitglied 18:35:58 12.06.2017   Titel:              Zitieren

Du hast recht; ich habe mich da schlecht ausgedrückt, und ich kann das bei erneutem Durchsehen auch inhaltlich nicht so stehenlassen.

DocShoe schrieb von der "Delphi-Unart", und ich hatte mich mit meinem Einwand auch auf die Sprache Delphi beziehen wollen. Die Konsequenzen für die Headerdateien habe ich ja separat aufgeführt. Aber wie du sagst: es ist eben auch nicht genau wie in Delphi.

Also, von vorne. An eine moderne Programmiersprache könnte man folgende Ansprüche stellen:

1. daß Schnittstellendefinitionen einander nicht beeinflussen
2. daß die Bedeutung eines Programms nicht von volatilen Umständen wie der Reihenfolge der Schnittstelleneinbindung beeinflußt wird
3. daß das Öffnen eines Namensraums nur eine lokale Schreiberleichterung ist und die Schnittstelle nicht verändert
4. daß auch Symbole aus nicht geöffneten Namensräumen erreichbar sind

C# erfüllt alle vier Ansprüche. Das bedeutet, wir können Namensräume, mit denen wir arbeiten, einfach öffnen und Symbole nur dann qualifizieren, wenn es Mehrdeutigkeiten gibt, und wir tun das guten Gewissens, weil der Compiler im Zweifel die Qualifizierung erzwingt. Wir können auch mit Namensräumen arbeiten, die wir nicht öffnen wollen (z.B. weil sie eine wünschensunwerte Menge an Konflikten verursachen würden).

Delphi erfüllt #1 und #3, aber nicht #2 (weil das zuletzt referenzierte Unit bevorzugt wird) und nicht #4. Wie in C# kann man alle Namensräume öffnen, mit denen man arbeitet, und nur explizit qualifizieren, um Mehrdeutigkeiten auszuweichen. Aber ob das gut geht, ist ein bißchen Glückssache, und man muß auch nicht genehme Namensräume öffnen, um mit ihnen zu arbeiten.

C++ mit Headerdateien erfüllt nur #4: Headerdateien können einander in die Quere kommen; die Headerreihenfolge kann auch die Bedeutung eines Programms verändern; und das Öffnen eines Namensraums ist nicht nur eine lokale Schreiberleichterung, sondern verändert den umliegenden Namensraum. Deshalb ist die übliche Arbeitsweise mit C# und Delphi, möglichst viele Namensräume zu öffnen, in C++-Headerdateien gefährlich und verpönt.

Was ich also ausdrücken wollte: das standardmäßige Öffnen von Namensräumen ist an sich keine Unart, wenn die Sprache dazu paßt. Aber weil C++ die meisten meiner obigen Kriterien nicht erfüllt, sollte man es in Headerdateien eben bleibenlassen. Deshalb fand ich, daß "Delphi-Unart" das Problem nicht trifft. Ich würde "C++Builder-Unart" vorschlagen :)

_________________
"Hey, it compiles! Ship it!"
C++Builder Pages · Typsichere Format-Strings
Th69
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.03.2008
Beiträge: 4568
Beitrag Th69 Mitglied 19:11:07 12.06.2017   Titel:              Zitieren

OK, so stimme ich dir vollkommen zu. :live:
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 2695
Beitrag DocShoe Mitglied 08:35:05 13.06.2017   Titel:              Zitieren

audacia schrieb:

...
Deshalb fand ich, daß "Delphi-Unart" das Problem nicht trifft. Ich würde "C++Builder-Unart" vorschlagen :)


Das ist auch genau das, was ich eigentlich sagen wollte.

_________________
Die fünf häufigsten Anzeichen für Faulheit:
1.
C++ Forum :: VCL (C++ Builder) ::  Mehrdeutigkeit 'ULONG_PTR' und 'Wmplib_tlb::ULONG_PTR'   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.