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;
私の Bonjour フレームワークでは、アナウンスされたサービスがアクティブになった場合 (つまり、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;
これは厳密に必要だと思うよりも冗長です。確かに、Delphi 7 では非常に冗長な形式で完全に機能していました。デバッグを容易にするために、多くの操作を明示的な手順に拡張しました。たとえば、Delphi 2009 で「内部」で発生している可能性のある文字列ペイロードの暗黙的な変換を識別できるようにしました。
この乱雑に展開された形式でも、このコードは Delphi 7 でコンパイルして完全に動作しますが、Delphi 2009 でコンパイルして実行すると、サービスの通知がありません。
たとえば、このコードを Delphi 7 アプリケーションの一部として実行して_daap._tcp
サービス (iTunes 共有ライブラリ) を登録すると、iTunes の実行中のインスタンスにポップアップが表示されます。Delphi 2009 でまったく同じアプリケーションを変更せずに再コンパイルして実行すると、サービスが iTunes に表示されません。
dns-sdコマンド ライン ユーティリティで監視すると、同じ動作が得られます。つまり、Delphi 7 でコンパイルされたサービス コードは、Delphi 2009 でコンパイルされた期待どおりに動作します。
Bonjour API からエラーが発生しません。DNSServiceRegisterReplyコールバックが ErrorCode 0 (ゼロ)、つまり成功で呼び出されています。フラグで AutoRename を指定して NIL 名前パラメーターを指定すると、サービスに正しい名前が割り当てられます。デフォルト名。しかし、それでもサービスは iTunes に表示されません。
何が起こっているのか途方に暮れています。
コードの拡張からわかるように、私は Delphi 2009 の Unicode 実装によって導入される潜在的なエラーを追跡してきましたが、これは私をどこにも導いていないようです。
このコードは、元々、Bonjour API/SDK のバージョン 1.0.3 に対して開発されました。それ以来、何らかの形で関与していた場合に備えて、1.0.6 に更新しましたが、成功しませんでした。afaict 1.0.6 は、「プロパティ」を取得するための新しい関数を追加しただけで、現在、Bonjour バージョンを取得するための「DaemonVersion」プロパティのみをサポートしています。これは完全に機能しています。
注:現在のコードは、Delphi 7 では技術的に UTF8 セーフではないことを認識しています。Delphi 2009 が適用する自動変換をできるだけ単純にするために、明示的な変換を可能な限り排除しました。私の現在の目標は、これを Delphi 2009 で機能させ、そのソリューションから逆方向に作業して、以前のバージョンの Delphi と互換性のあるアプローチを見つけることです。
注:私は元々、宣伝されているサービスのブラウジング、つまりネットワーク上の実際の iTunes 共有ライブラリの識別にも問題がありました。これらの問題は、Delphi 2009 での Unicode 処理が原因で発生し、解決されました。私の Delphi 2009 コードは、実際の iTunes 共有ライブラリを識別し、その TXT レコードを照会することができます。機能していないのは、このサービス登録だけです。
私は愚かで明白な何かを見逃しているに違いありません。
誰かアイデアはありますか?!
アップデート
この問題に戻って、次のことを発見しました。
D2009 より前の IDE と D2009+ IDE を開いている場合 (D2006 と D2010 など)、同じプロジェクトを両方の IDE に同時にロードすると、次のようになります。
- 2006 でビルドして実行: 動作します - 私のサービス アナウンスメントは iTunes で取り上げられます
- D2010 に切り替えて実行 (ビルドなし): 最小限のコンパイル、実行、および動作を行います。
D2010 でフル ビルドを実行します。動作しなくなります
D2006 に切り替えて実行 (ビルドせずに): 動作しません
- D2006 でフル ビルドを行う: 再び動作する
これは誰かに他のアイデアを与えますか?