我对 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回调,错误代码为 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 记录。只有这个服务注册不起作用。
我一定错过了一些愚蠢而明显的东西。
有没有人有什么想法?!
更新
回到这个问题后,我现在发现了以下内容:
如果我打开了一个 pre-D2009 和一个 D2009+ IDE(例如 D2006 和 D2010),同时将同一个项目加载到两个 IDE 中:
- 在 2006 年构建和运行:它有效 - 我的服务公告被 iTunes 接收
- 切换到 D2010 并运行(无需构建):它进行了最小的编译、运行和工作。
在 D2010 中进行完整构建:它停止工作
切换回 D2006 并运行(不构建):它不起作用
- 在 D2006 中进行完整构建:它再次工作
这会给任何人其他想法吗?