Código ZeroConf / Bonjour que funciona no Delphi 7 não funciona em 2009

Eu tenho a seguinte declaração para o 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;

Na minha estrutura do Bonjour, tenho a seguinte resposta a um serviço anunciado que está sendo ativado (ou seja, para realmente começar a se anunciar, via Bonjour):

  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;

Isso é mais detalhado do que eu acho que é estritamente necessário, certamente estava funcionando perfeitamente no Delphi 7 de forma muito menos detalhada. Eu tenho expandido muitas operações em etapas explícitas para facilitar a depuração, por exemplo ser capaz de identificar quaisquer transformações implícitas de cargas úteis de strings que possam estar ocorrendo "under the hood" no Delphi 2009.

Mesmo nessa forma expandida desordenada, este código compila e funciona perfeitamente no Delphi 7, mas se eu compilar e executar com o Delphi 2009, não receberei nenhum anúncio do meu serviço.

Por exemplo, se eu executar este código como parte de um aplicativo Delphi 7 para registrar um_daap._tcp serviço (uma biblioteca compartilhada do iTunes) Eu vejo o pop-up em uma instância em execução do iTunes. Se eu recompilar o mesmo aplicativo sem modificação no Delphi 2009 e executá-lo, eu o façonão ver meu serviço aparecendo no iTunes.

Eu obtenho o mesmo comportamento ao monitorar com odns-sd utilitário de linha de comando. Ou seja, o código de serviço compilado com o Delphi 7 se comporta como eu esperava, compilado no Delphi 2009 - nada.

Eu não estou recebendoqualquer erros da API do Bonjour - oDNSServiceRegisterReply O retorno de chamada está sendo chamado com um ErrorCode de 0 (zero), ou seja, com sucesso, e se eu fornecer um parâmetro de nome NIL com AutoRename especificado nos sinalizadores, meu serviço receberá o nome padrão correto. Mas ainda assim o serviço não aparece no iTunes.

Não sei o que está acontecendo.

Como você pode dizer a partir da expansão do código, eu tenho perseguido possíveis erros sendo introduzidos pela implementação Unicode no Delphi 2009, mas isso parece estar me levando a lugar nenhum.

O código foi originalmente desenvolvido contra a versão 1.0.3 da Bonjour API / SDK. Desde então, atualizei para a versão 1.0.6, caso isso estivesse de alguma forma envolvido, sem sucesso algum. afaict 1.0.6 simplesmente adicionou uma nova função para obter "propriedades", que atualmente suporta apenas uma propriedade "DaemonVersion" para obter a versão Bonjour - isto está funcionando perfeitamente.

NOTA: Estou ciente de que o código, tal como está, não é tecnicamente seguro com UTF8 no Delphi 7 - eliminei as conversões explícitas o máximo possível, de modo a manter as coisas o mais simples possível para as conversões automáticas que o Delphi 2009 aplica. Meu objetivo agora é fazer com que isso funcione no Delphi 2009 e, em seguida, trabalhe de trás para frente nessa solução para encontrar uma abordagem compatível para as versões anteriores do Delphi.

NOTE TAMBÉM: Originalmente, também tive problemas em procurar serviços anunciados, ou seja, identificar uma biblioteca compartilhada real do iTunes na rede. Esses problemas foram causados ​​pelo manuseio do Unicode no Delphi 2009 e foram resolvidos. Meu código Delphi 2009 é tão capaz de identificar uma biblioteca compartilhada real do iTunes e consultar seus registros TXT. É apenas esse registro de serviço que não está funcionando.

Eu devo estar perdendo algo estúpido e óbvio.

Alguém tem alguma idéia?!

ATUALIZAR

Tendo retornado a este problema, descobri agora o seguinte:

Se eu tiver um pré-D2009 e um D2009 + IDE aberto (por exemplo, D2006 e D2010) com omesmo projeto carregado no IDE simultaneamente:

Construa e execute em 2006: Funciona - meu anúncio de serviço é coletado pelo iTunesMude para D2010 e execute (sem construir): Ele faz uma compilação mínima, roda e funciona.

Faça uma construção completa no D2010: ele pára de funcionar

Volte para o D2006 e corra (sem construir): não funciona

Faça uma construção completa em D2006: funciona novamente

Isso dá alguma idéia a alguém?

questionAnswers(4)

yourAnswerToTheQuestion