为什么Direct2D和DirectWrite不使用传统的COM对象?

时间:2010-05-14 21:53:40

标签: c# .net com direct2d directwrite

我正在使用C#中的一个小型2D游戏引擎,并决定使用Direct2D和DirectWrite进行渲染。我知道有Windows API代码包和SlimDX,但我真的很喜欢从头开始编写接口。我试图在没有托管C ++的情况下这样做,但Direct2D和DirectWrite似乎没有使用传统的COM对象。它们定义了从IUnknown派生的接口,但似乎没有办法从C#与COM互操作实际使用它们。 d2d1.h中有IID,但没有CLSID。

当然,我对COM互操作很新,所以也许我只是错过了一些东西。有人可以对这种情况有所了解吗?

3 个答案:

答案 0 :(得分:8)

知道了。您不能直接创建对象,但d2d1.dll包含一个名为D2D1CreateFactory的导出,它返回ID2DFactory接口。使用它,您可以实现没有托管C ++的Direct2D包装器。

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界面具有相应的GuidInterfaceType(ComInterfaceType.InterfaceIsIUnknown)属性。

答案 1 :(得分:6)

“用于Microsoft®.NETFramework的Windows®API代码包”具有允许访问Direct2D和DirectWrite的托管库。

http://code.msdn.microsoft.com/WindowsAPICodePack

更新

虽然DirectX包装器是用托管C ++编写的,但它们生成了托管库。根据事物的外观,这些可以从C#中使用。下载中包含的大量示例正是如此,即使用C#中的托管C ++ Direct包装器库。

在我自己的C#应用​​程序中使用Windows 7功能会非常好,所以我目前正在安装Window7 SDK(这样我就可以构建托管的C ++ DirectX解决方案)并且会给整个事情带来重击。

我按照以下说明操作:

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

更新2

按照上面链接中的说明,我编译了托管C ++库,你确实可以很容易地从C#中使用它们。

现在我不确定我是否理解正确,但您是否正在考虑使用C#中的Direct2D和DirectWrite,或者它必须是COM或P \ Invoke。

我非常怀疑会有一个COM包装器,因为它是一种不匹配的技术。对于你在图形编程中获得的那种高频方法调用模式来说,COM并不是很好的设计 - 它太慢了。

如果您真的想要进行P \ Invoke,您可以随时查看DirectX头文件(在Windows 7 SDK中)并使用工具创建所有P \ Invoke调用存根,例如。

http://www.pinvoker.com/

这可能是一个主要的PITA虽然以这种方式开发包装。

答案 2 :(得分:2)

Codeplex上有一个项目,为Direct2D提供托管包装器。我不知道它是否有用,但很可能源代码将帮助您入门。

http://direct2dsharp.codeplex.com/