Почему Direct2D и DirectWrite не используют традиционные COM-объекты?
Я играю с небольшим движком 2D игры в C# и решил использовать Direct2D и DirectWrite для рендеринга. Я знаю, что есть Windows API Code Pack и SlimDX, но мне бы очень хотелось покопаться и написать интерфейс с нуля. Я пытаюсь сделать это без Managed C++, но Direct2D и DirectWrite, похоже, не используют традиционные объекты COM. Они определяют интерфейсы, которые происходят от IUnknown
, но, кажется, нет никакого способа использовать их из C# с COM-взаимодействием. Есть IID в d2d1.h
, но без CLSID.
Конечно, я действительно новичок в COM взаимодействии, так что, возможно, я просто что-то упустил. Может кто-то пролить свет на эту ситуацию?
3 ответа
Понял. Вы не можете создавать объекты напрямую, но d2d1.dll
содержит экспорт под названием D2D1CreateFactory
который возвращает ID2DFactory
интерфейс. Используя это, вы можете реализовать оболочку Direct2D без Managed C++.
public static class Direct2D1Util {
public const string IID_ID2D1Factory =
"06152247-6f50-465a-9245-118bfd3b6007";
[DllImport("d2d1.dll", PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Interface)]
private static extern object D2D1CreateFactory(D2D1_FACTORY_TYPE factoryType,
[MarshalAs(UnmanagedType.LPStruct)] Guid riid,
D2D1_FACTORY_OPTIONS pFactoryOptions);
public static ID2D1Factory CreateFactory() {
D2D1_FACTORY_OPTIONS opts = new D2D1_FACTORY_OPTIONS();
object factory = D2D1CreateFactory(
D2D1_FACTORY_TYPE.D2D1_FACTORY_TYPE_SINGLE_THREADED,
new Guid(IID_ID2D1Factory), opts);
return (ID2D1Factory)factory;
}
}
Я не буду включать все типы, потому что все они определены в d2d1.h
, но вот как использовать код для получения фабрики:
ID2DFactory factory = Direct2D1Util.CreateFactory();
Убедитесь, что ваш ID2DFactory
интерфейс имеет соответствующий Guid
а также InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
атрибутов.
Пакет Windows® API Code Pack для Microsoft® .NET Framework содержит управляемые библиотеки, которые обеспечивают доступ к Direct2D и DirectWrite.
http://code.msdn.microsoft.com/WindowsAPICodePack
Обновить
Хотя оболочки DirectX написаны на управляемом C++, они создают управляемые библиотеки. Судя по всему, они могут быть использованы в C#. Есть много примеров, включенных в загрузку, которые делают именно это, то есть используют управляемые библиотеки оболочки C++ Direct из C#.
Использование функций Windows 7 в моем собственном приложении на C# было бы очень неплохо, поэтому я в настоящее время устанавливаю Windows7 SDK (чтобы я мог создать управляемое решение C++ DirectX) и предоставлю все это.
Я следую инструкциям по адресу:
Обновление 2
Следуя инструкциям в приведенной выше ссылке, я собрал управляемые библиотеки C++, и вы действительно можете очень легко использовать их из C#.
Теперь я не уверен, правильно ли я понимаю, но вы просто ищете какой-то способ использования Direct2D и DirectWrite из C# или это должен быть COM или P\Invoke.
Я бы очень сомневался, что будет COM-обертка, так как это несовпадающая технология. COM не очень хорошо спроектирован для высокочастотных шаблонов вызовов методов, которые вы получаете в графическом программировании - он слишком медленный.
Если вы действительно хотите сделать P \ Invoke, вы всегда можете посмотреть заголовочные файлы DirectX (в Windows 7 SDK) и использовать инструмент для создания всех ваших заглушек вызовов P \ Invoke, например
Вероятно, это было бы основной PITA, хотя бы разрабатывать обертку таким образом.
В codeplex есть проект, который предоставляет управляемые оболочки для Direct2D. Я понятия не имею, если это хорошо, но, скорее всего, исходный код поможет вам начать.