ZeroConf / Bonjour-Code, der in Delphi 7 funktioniert und in 2009 nicht funktioniert

Ich habe die folgende Deklaration für DNSServiceRegister:

  function DNSServiceRegister
      (
      var sdRef: TDNSServiceRef;
      const flags: TDNSServiceFlags;
      const interfaceIndex: uint32_t;
      const name: PUTF8String;                    //* may be NULL */
      const regType: PUTF8String;
      const domain: PUTF8String;                  //* may be NULL */
      const host: PUTF8String;                    //* may be NULL */
      const port: uint16_t;
      const txtLen: uint16_t;
      const txtRecord: Pointer;                 //* may be NULL */
      const callBack: TDNSServiceRegisterReply; //* may be NULL */
      const context: Pointer                    //* may be NULL */
      ): TDNSServiceErrorType; stdcall; external DNSSD_DLL;

In meinem Bonjour-Framework habe ich die folgende Antwort darauf, dass ein angekündigter Dienst aktiviert wird (d. H., Um sich über Bonjour selbst anzumelden):

  procedure TAnnouncedService.Activate;
  var
    flags: Cardinal;
    name: UTF8String;
    svc: UTF8String;
    pn: PUTF8String;
    ps: PUTF8String;
  begin
    fPreAnnouncedServiceName := ServiceName;

    inherited;

    if AutoRename then
      flags := 0
    else
      flags := kDNSServiceFlagsNoAutoRename;  { - do not auto-rename }

    if (ServiceName <> '') then
    begin
      name  := ServiceName;
      pn    := PUTF8String(name);
    end
    else
      pn := NIL;

    svc := ServiceType;
    ps  := PUTF8String(svc);

    CheckAPIResult(DNSServiceRegister(fHandle,
                                      flags,
                                      0 { interfaceID - register on all interfaces },
                                      pn,
                                      ps,
                                      NIL { domain - register in all available },
                                      NIL { hostname - use default },
                                      ReverseBytes(Port),
                                      0   { txtLen },
                                      NIL { txtRecord },
                                      DNSServiceRegisterReply,
                                      self));
    TBonjourEventHandler.Create(fHandle);
  end;

Dies ist ausführlicher als ich denke, dass es unbedingt sein muss, sicherlich hat es in Delphi 7 in einer viel weniger ausführlichen Form einwandfrei funktioniert. Ich habe viele Operationen zu expliziten Schritten erweitert, um das Debuggen zu erleichtern, z. implizite Transformationen von String-Nutzdaten identifizieren zu können, die in Delphi 2009 möglicherweise "under the hood" auftreten.

Selbst in dieser unordentlichen erweiterten Form wird dieser Code in Delphi 7 kompiliert und funktioniert einwandfrei. Wenn ich ihn jedoch mit Delphi 2009 kompiliere und ausführe, wird mein Dienst nicht angekündigt.

Wenn ich beispielsweise diesen Code als Teil einer Delphi 7-Anwendung zum Registrieren von a_daap._tcp Dienst (eine gemeinsam genutzte iTunes-Mediathek) Ich sehe, dass er in einer laufenden Instanz von iTunes angezeigt wird. Wenn ich dieselbe Anwendung ohne Änderungen in Delphi 2009 erneut kompiliere und sie ausführe, tue ich dasnicht Mein Dienst wird in iTunes angezeigt.

Ich bekomme das gleiche Verhalten beim Überwachen mit demdns-sd Befehlszeilenprogramm. Das heißt, der mit Delphi 7 kompilierte Service-Code verhält sich wie erwartet in Delphi 2009 kompiliert - nichts.

Ich verstehe nichtirgendein Fehler von der Bonjour API - dieDNSServiceRegisterReply Rückruf wird mit einem ErrorCode von 0 (Null) aufgerufen, d. h. Erfolg. Wenn ich einen NIL-Namensparameter mit in den Flags angegebenem AutoRename bereitstelle, wird meinem Dienst der richtige Standardname zugewiesen. Der Dienst wird jedoch immer noch nicht in iTunes angezeigt.

Ich bin ratlos, was los ist.

Wie Sie vielleicht an der Erweiterung des Codes ablesen können, habe ich nach potenziellen Fehlern gesucht, die durch die Unicode-Implementierung in Delphi 2009 verursacht wurden, aber dies scheint mich nicht weiterzubringen.

Der Code wurde ursprünglich für Version 1.0.3 der Bonjour API / SDK entwickelt. Ich habe seitdem auf 1.0.6 aktualisiert, falls das irgendwie involviert war, ohne Erfolg. afaict 1.0.6 hat lediglich eine neue Funktion zum Abrufen von "properties" hinzugefügt, die derzeit nur eine "DaemonVersion" -Eigenschaft zum Abrufen der Bonjour-Version unterstützt - dies funktioniert einwandfrei.

HINWEIS: Mir ist bewusst, dass der aktuelle Code in Delphi 7 technisch nicht UTF8-sicher ist. Ich habe explizite Konvertierungen so weit wie möglich eliminiert, um die Dinge für die von Delphi 2009 angewendeten automatischen Konvertierungen so einfach wie möglich zu halten. Mein Ziel ist es nun, dass dies in Delphi 2009 funktioniert und dann von dieser Lösung zurückgegriffen wird, um hoffentlich einen kompatiblen Ansatz für frühere Versionen von Delphi zu finden.

HINWEIS AUCH: Ursprünglich hatte ich auch Probleme beim Suchen nach beworbenen Diensten, d. H. Beim Identifizieren einer tatsächlichen iTunes-Bibliothek im Netzwerk. Diese Probleme wurden durch die Unicode-Behandlung in Delphi 2009 verursacht und behoben. Mein Delphi 2009-Code kann auch eine tatsächliche iTunes-Bibliothek identifizieren und deren TXT-Einträge abfragen. Es ist nur diese Serviceregistrierung, die nicht funktioniert.

Mir muss etwas Dummes und Offensichtliches fehlen.

Hat jemand irgendwelche Ideen ?!

AKTUALISIEREN

Nachdem ich auf dieses Problem zurückgekommen bin, habe ich nun Folgendes entdeckt:

Wenn ich eine Pre-D2009 und eine D2009 + IDE offen habe (z. B. D2006 und D2010) mit dergleich Projekt gleichzeitig in beide IDE's geladen:

Build and Run unter 2006: Es funktioniert - meine Service-Ankündigung wird von iTunes übernommenWechseln Sie zu D2010 und führen Sie es aus (ohne es zu erstellen): Es führt eine minimale Kompilierung durch, läuft und funktioniert.

Führe einen vollständigen Build in D2010 durch: Es funktioniert nicht mehr

Wechsle zurück zu D2006 und laufe (ohne Gebäude): Es funktioniert nicht

Führe einen vollständigen Build in D2006 durch: Es funktioniert wieder

Gibt dies jemand andere Ideen?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage