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

发布于 2024-09-01 18:56:42 字数 344 浏览 8 评论 0原文

我正在尝试用 C# 编写一个小型 2D 游戏引擎,并决定使用 Direct2D 和 DirectWrite 进行渲染。我知道有 Windows API Code Pack 和 SlimDX,但我真的很想深入研究并从头开始编写一个界面。我尝试在不使用托管 C++ 的情况下完成此操作,但 Direct2D 和 DirectWrite 似乎不使用传统的 COM 对象。它们定义了从 IUnknown 派生的接口,但似乎无法通过 COM 互操作在 C# 中实际使用它们。 d2d1.h 中有 IID,但没有 CLSID。

当然,我对 COM 互操作非常陌生,所以也许我只是错过了一些东西。有人可以阐明这种情况吗?

I'm toying with a little 2D game engine in C# and decided to use Direct2D and DirectWrite for rendering. I know there's the Windows API Code Pack and SlimDX, but I'd really like to dig in and write an interface from scratch. I'm trying to do it without Managed C++, but Direct2D and DirectWrite don't appear to use traditional COM objects. They define interfaces that derive from IUnknown, but there appears to be no way to actually use them from C# with COM interop. There are IIDs in d2d1.h, but no CLSID.

Of course, I'm really new to COM interop, so perhaps I'm just missing something. Can someone shed some light on this situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

傲鸠 2024-09-08 18:56:42

知道了。您无法直接创建对象,但 d2d1.dll 包含一个名为 D2D1CreateFactory 的导出,该导出返回 ID2DFactory 接口。使用它,您可以实现 Direct2D 包装器,而无需托管 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) 属性。

Got it. You can't create the objects directly, but d2d1.dll contains an export called D2D1CreateFactory that returns an ID2DFactory interface. Using this, you can implement a Direct2D wrapper without 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;
    }
}

I won't include all of the types, because they're all defined in d2d1.h, but here's how to use the code to get a factory:

ID2DFactory factory = Direct2D1Util.CreateFactory();

Make sure your ID2DFactory interface has the appropriate Guid and InterfaceType(ComInterfaceType.InterfaceIsIUnknown) attributes.

§普罗旺斯的薰衣草 2024-09-08 18:56:42

“Microsoft® .NE​​T Framework 的 Windows® API 代码包”具有允许访问 Direct2D 和 DirectWrite 的托管库。

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

更新

而 DirectX 包装器是用托管 C++,他们生成托管库。从表面上看,这些可以在 C# 中使用。下载中似乎有大量示例可以实现此目的,即使用 C# 中的托管 C++ 直接包装器库。

在我自己的 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。

The "Windows® API Code Pack for Microsoft® .NET Framework" has managed libraries that allow access to Direct2D and DirectWrite.

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

Update

Whilst the DirectX wrappers are written in managed C++, they produce managed libraries. By the looks of things these can be used from C#. There look to be plenty of examples included in the download that do exactly this i.e. use the managed C++ Direct wrapper libraries from C#.

Using Windows 7 features in my own C# application would be very nice, so I am currently installing the Window7 SDK (so that I can build the managed C++ DirectX solution) and will give the whole thing a bash.

I am following the instructions at:

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

Update 2

Following the instructions in the above link I got the managed C++ libraries compiled and you can indeed use them from C# very easily.

Now I'm not sure if I understand correctly, but are you just looking at some way of using Direct2D and DirectWrite from C#, or does it have to be COM or P\Invoke.

I would very much doubt there would be a COM wrapper, as it's a mismatched technology. COM is not really well designed for the sort of high-frequency method call patterns that you get in Graphics programming - it is way too slow.

If you really want to do P\Invoke you could always look at the DirectX header files (in the Windows 7 SDK) and use a tool to create all your P\Invoke call stubs, e.g.

http://www.pinvoker.com/

That would probably be a major PITA though to develop a wrapper this way.

又爬满兰若 2024-09-08 18:56:42

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

http://direct2dsharp.codeplex.com/

There's a project on codeplex that provides managed wrappers for Direct2D. I have no idea if it's any good, but most likely the source code will help you get started.

http://direct2dsharp.codeplex.com/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文