Невозможно установить TXTRecord с помощью Bonjour SDK (COM Wrapper — CComObject & lt; CTXTRecord & gt; *)

Похоже, что Apple Bonjour SDK не устанавливает TXTRecord при публикации сервиса из-за взаимодействия COM / .NET.

Вкратце, есть класс COM для создания текстовой записи:

[
odl,
uuid(8FA0889C-5973-4FC9-970B-EC15C925D0CE),
helpstring("ITXTRecord Interface"),
dual,
nonextensible,
oleautomation
]
interface ITXTRecord : IDispatch {
[id(0x00000001), helpstring("method SetValue")]
HRESULT SetValue(
[in] BSTR key,
[in] VARIANT value);
...
};

[
uuid(AFEE063C-05BA-4248-A26E-168477F49734),
helpstring("TXTRecord Class")
]
coclass TXTRecord {
[default] interface ITXTRecord;
};

Соответствующий код C ++ находится там: https://github.com/Apple-FOSS-Mirror/mDNSResponder/blob/master/mDNSWindows/DLLX/TXTRecord.cpp#L38

И есть способ регистрации сервиса в классе IDNSSDService:

    [id(0x00000004), helpstring("method Register")]
HRESULT Register(
[in] DNSSDFlags flags,
[in] unsigned long ifIndex,
[in] BSTR name,
[in] BSTR regtype,
[in] BSTR domain,
[in] BSTR host,
[in] unsigned short port,
[in] ITXTRecord* record,
[in] IDNSSDEventManager* eventManager,
[out, retval] IDNSSDService** service);

Соответствующий метод C ++ есть: https://github.com/Apple-FOSS-Mirror/mDNSResponder/blob/master/mDNSWindows/DLLX/DNSSDService.cpp#L494

Тогда в .NET:

    let txtRecord = new TXTRecordClass()
txtRecord.SetValue("test", "test")
_service.Register(enum<DNSSDFlags>(0), uint32(0), author, "_webdav._tcp", null, null, uint16(80), txtRecord, _events)

SetValue работает хорошо, и был вызван метод CTXTRecord :: SetValue. Указатель this скажем, 0x004573ec.

Сложность в том, что указатель на record в методе Register отличается и не равен 0x004573ec! Он указывает на какой-то другой адрес, обычно недалеко от сохраненного указателя (0x004573ec). Хорошо, может быть, это какая-то обертка. Плохо то, что Publish позже брось это CComObject<CTXTRecord>* но похоже, что указанный объект не инициализирован (имеет нулевые поля). Я пытался использовать разные подходы, такие как передача txtRecord По ссылке ищите обходной путь, но здесь ничего нет.

Похоже, что в IDL отсутствует пропущенная директива или подход, реализованный в Publish неверно, но мои навыки взаимодействия с .NET / C ++ / COM недостаточно хороши, чтобы найти решение. Есть идеи?

0

Решение

Эта оболочка COM имеет действительно безобразный хак:

STDMETHODIMP CDNSSDService::Register(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, BSTR host, USHORT port, ITXTRecord *record, IDNSSDEventManager *eventManager, IDNSSDService **service)
{
// ...

if ( record )
{
CComObject< CTXTRecord > * realTXTRecord;

realTXTRecord = ( CComObject< CTXTRecord >* ) record;

// ...
}

// ...
}

Который обречен на провал с маршалированными указателями интерфейса, из объектов, которые принадлежат другой квартире. Я полагаю, ваш ITXTRecord создается в другом процессе, то есть в другой квартире, так что приведение принимает COM-прокси вместо реального объекта.

Один из способов обойти это — найти способ получить ссылку на TXTRecord объект, созданный COM-сервером. Я нашел два места в оболочке COM (Вот а также Вот), которые создают объект и два места (Вот а также Вот) где этот объект предоставляется клиенту.

Следуя ссылкам, кажется, вы должны позвонить или CDNSSD::Resolve с IResolveListener или же1. CDNSSDService::Resolve с IDNSSDEventManager, указывая на объект, который также реализует _IDNSSDEvents (это может быть ваш собственный объект), который получит «реальный» ITXTRecord в качестве аргумента ServiceResolved метод события.

Таким образом, вы можете сделать фиктивное решение с помощью интеллектуального обработчика событий, который захватывает TXTRecord, Если вы найдете надежный хост (например, localhost или 127.0.0.1), вы, возможно, превратите его в фабричный метод. На самом деле я не проверял это, но из кода, если на хосте нет записи TXT, вы просто получите пустую.


  1. Я не могу найти DNSSD.h для проверки IResolveListener и декларация CDNSSD сам.
2

Другие решения


По вопросам рекламы [email protected]