Почему 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) и предоставлю все это.

Я следую инструкциям по адресу:

http://blogs.msdn.com/msaleh/archive/2009/08/25/introducing-directx-features-of-windows-api-code-pack.aspx

Обновление 2

Следуя инструкциям в приведенной выше ссылке, я собрал управляемые библиотеки C++, и вы действительно можете очень легко использовать их из C#.

Теперь я не уверен, правильно ли я понимаю, но вы просто ищете какой-то способ использования Direct2D и DirectWrite из C# или это должен быть COM или P\Invoke.

Я бы очень сомневался, что будет COM-обертка, так как это несовпадающая технология. COM не очень хорошо спроектирован для высокочастотных шаблонов вызовов методов, которые вы получаете в графическом программировании - он слишком медленный.

Если вы действительно хотите сделать P \ Invoke, вы всегда можете посмотреть заголовочные файлы DirectX (в Windows 7 SDK) и использовать инструмент для создания всех ваших заглушек вызовов P \ Invoke, например

http://www.pinvoker.com/

Вероятно, это было бы основной PITA, хотя бы разрабатывать обертку таким образом.

В codeplex есть проект, который предоставляет управляемые оболочки для Direct2D. Я понятия не имею, если это хорошо, но, скорее всего, исходный код поможет вам начать.

http://direct2dsharp.codeplex.com/

Другие вопросы по тегам