尝试通过互操作将 C++ 转换为 C#

2024-01-08

我有一个用 C++ 调用 EGL 的程序。我想在 C# 中进行相同的调用,但 C# 中似乎没有等效的概念。

当执行上下文进入 C++ EGL 代码时,我收到读/写访问被拒绝错误。

这是我尝试将 C++ 程序转换为 C# 的代码:

PropertySet^ surfaceCreationProperties = ref new PropertySet();
surfaceCreationProperties->Insert(ref new String(EGLNativeWindowTypeProperty), somethingOtherThanAWindow);

mEglSurface = eglCreateWindowSurface(mEglDisplay, config, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes));

我有一个 C# 类,它将 C# EGL 调用转换为 C++ 调用。我相信 C++ 是非托管的,尽管我不知道如何确定地告诉你。

C# 类如下所示:

public static IntPtr CreateWindowSurface(IntPtr dpy, IntPtr config, IntPtr win, int[] attrib_list)
{
    IntPtr retValue;

    unsafe {
        fixed (int* p_attrib_list = attrib_list)
        {
            retValue = Delegates.peglCreateWindowSurface(dpy, config, win, p_attrib_list);
        }
    }
    return (retValue);
}

更多该代码可以在这里看到:https://github.com/luca-piccioni/OpenGL.Net/blob/master/OpenGL.Net/Egl.VERSION_1_0.cs#L751 https://github.com/luca-piccioni/OpenGL.Net/blob/master/OpenGL.Net/Egl.VERSION_1_0.cs#L751

你可能会注意到这个方法有一个IntPtr win-- 这就是我要经过的地方PropertySet。通常我相信这将是System.Windows.Forms.Control,但在 C++ EGL 代码中进行了一些检查,看看它是否是,或者是否是一个PropertySet.

被调用的C++方法是这样的:

EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)

更多内容可以在这里看到:https://github.com/Microsoft/angle/blob/ms-holographic-experimental/src/libGLESv2/entry_points_egl.cpp#L241 https://github.com/Microsoft/angle/blob/ms-holographic-experimental/src/libGLESv2/entry_points_egl.cpp#L241

正如您所看到的,C++ 方法需要 EGLNativeWindowType。我不太确定 IInspectable 和 PropertSet 之间的关系是什么 - 可以强制转换这似乎很奇怪。

EGLNativeWindowType 具有以下类型定义:

typedef HWND EGLNativeWindowType;

这意味着它必须是某种窗口句柄。我不明白 PropertySet 如何成为窗口句柄。

我怀疑主要问题在于选择正确的对象类型以传递给 C# EGL 实现。 PropertySet 看起来可能是正确的选择,但reinterpret_cast 确实让我失望。

有人能引导我完成这个吗?


通常我相信这将是一个 System.Windows.Forms.Control...

这是一个极其错误的假设。理解打字的意义需要写三本书,在这样的答案中很难做到。如果您确实打算从 Winforms 应用程序执行此操作,请立即停止,那永远行不通。

OpenGL使用very松散类型,其 api 函数的参数只不过是void*,一个原始指针。这使得它非常灵活,但它是really重要的是指针实际指向什么。如果客户端程序和视频适配器接口不同意丝毫这样你的程序就会构建得很好,但会在运行时以完全无法诊断的方式崩溃和烧毁。 Microsoft 放弃 OpenGL 并决定创建自己的 DirectX 的一个主要原因就是结果。

它也使用指针,但它们是更智能的类型,它们支持运行时的类型发现。他们是IUnknown指针,其 QueryInterface() 方法允许查明对象是否支持特定的预期接口。您在这里看到的风格与指针完全相同,IInspectable是比 IUnknown 稍微聪明的版本,也是所有 WinRT 类实现的基本接口。你真的do必须通过 IInspectable*,因为这是 ANGLE 端口所期望的。

您通常期望您可以通过ICoreWindow接口指针并完成它,这就是窗口的 WinRT 接口。然而,渲染器需要的信息不仅仅是 ICoreWindow。不太清楚为什么,我认为这与 WinRT 中的分辨率独立性有关。它also需要知道表面尺寸和比例因子。

问题是,OpenGL 没有办法传递该信息。所以微软程序员使用了一种非常做作的技巧,而不是adding一个传递此信息的函数,他/使用了传递任何类型的 IInspectable* 的能力,他传递了一个IMap<String^, IInspectable*>指针。基本上是一个属性包,ANGLE 端口中的 CoreWindowNativeWindow.cpp 在其 CoreWindowNativeWindow::initialize() 函数中再次从包中挖掘出属性。

PropertySet 是 C++ 语言投影中的一个具体类,它实现IMap<K, V>。请注意它是特定于 C++ 的,在 C# 中你可以使用Dictionary<string, IntPtr>反而。 CLR 中内置的语言投影会自动将托管字典映射到本机 IMap 接口。

哦,高兴,更多 IntPtrs。 IInspectable* 完全隐藏在您在 C# 中使用的语言投影中,这并不容易。我 98% 确定您可以使用Marshal.GetIUnknownForObject() https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getiunknownforobject.aspx获得一个有效的指针,即使它是错误的风格。由于 C++ 代码做了正确的事情并使用了 QueryInterface :) 之后您必须调用 Marshal.Release() 进行清理,否则会导致内存泄漏。

请注意,这有强烈的暗示你做错了事。我想你是的,微软提供这个 ANGLE 叉子只是为了one原因。他们试图让公司轻松地将 iOS 游戏移植到 WinRT/UWP。有必要让商店里充满顾客喜欢的游戏。 ANGLE 移植的目的只是为了让以 ObjectiveC 或 C++(用于编写这些游戏的语言)开头的代码易于使用。

They could使使用 Javascript 或 C# 等语言的库变得更加容易,但他们没有这么做,因为没有必要。如果您必须将使用 OpenGL 的 C++ 代码转换为 C#,那么您很可能会much如果您使用 DirectX,效果会更好。预计其他功能会遇到更多这种类型的映射麻烦,并对实验性 HoloLens 端口感到厌倦。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试通过互操作将 C++ 转换为 C# 的相关文章

  • 为什么大多数 C 开发人员使用 Define 而不是 const? [复制]

    这个问题在这里已经有答案了 在许多程序中 define与常量具有相同的用途 例如 define FIELD WIDTH 10 const int fieldWidth 10 我通常认为第一种形式优于另一种形式 它依赖于预处理器来处理基本上是
  • 向 ExpandoObject 添加方法时,“关键字 'this' 在静态属性、静态方法或静态字段初始值设定项中无效”

    我尝试向 ExpandoObject 添加一个动态方法 该方法将返回属性 动态添加 给它 但它总是给我错误 我在这里做错了什么吗 using System using System Collections Generic using Sys
  • 如何在 Android NDK 中创建新的 NativeWindow 而无需 Android 操作系统源代码?

    我想编译一个 Android OpenGL 控制台应用程序 您可以直接从控制台启动 Android x86 运行 或者从 Android x86 GUI 内的 Android 终端应用程序运行 这个帖子 如何在 Android NDK 中创
  • C++ 异步线程同时运行

    我是 C 11 中线程的新手 我有两个线程 我想让它们同时启动 我可以想到两种方法 如下 然而 似乎它们都没有按照我的预期工作 他们在启动另一个线程之前启动一个线程 任何提示将不胜感激 另一个问题是我正在研究线程队列 所以我会有两个消费者和
  • 如何从 C# 控制器重定向到外部 url

    我使用 C 控制器作为网络服务 在其中我想将用户重定向到外部网址 我该怎么做 Tried System Web HttpContext Current Response Redirect 但没有成功 使用控制器的重定向 http msdn
  • ASP MVC:服务应该返回 IQueryable 的吗?

    你怎么认为 你的 DAO 应该返回一个 IQueryable 以便在你的控制器中使用它吗 不 您的控制器根本不应该处理任何复杂的逻辑 保持苗条身材 模型 而不是 DAO 应该将控制器返回给视图所需的所有内容 我认为在控制器类中看到查询 甚至
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • 如何将“外部模板”与由同一类中的模板化成员使用的嵌套类一起使用?

    首先 一些背景信息 我尝试以 Herb Sutter 在他的解决方案中介绍的方式使用 Pimpl 习语 得到了 101 http herbsutter com gotw 101 这在头文件中看起来像这样 include pimpl h h
  • Qt 创建布局并动态添加小部件到布局

    我正在尝试在 MainWindow 类中动态创建布局 我有四个框架 它们是用网格布局对象放置的 每个框架都包含一个自定义的 ClockWidget 我希望 ClockWidget 对象在调整主窗口大小时相应地调整大小 因此我需要将它们添加到
  • 如何重置捕获像素的值

    我正在尝试创建一个 C 函数 该函数返回屏幕截图位图中每四个像素的 R G 和 B 值 这是我的代码的一部分 for int ix 4 ix lt 1366 ix ix 4 x x 4 for int iy 3 iy lt 768 iy i
  • 如何在c#中的内部类中访问外部类的变量[重复]

    这个问题在这里已经有答案了 我有两个类 我需要声明两个类共有的变量 如果是嵌套类 我需要访问内部类中的外部类变量 请给我一个更好的方法来在 C 中做到这一点 示例代码 Class A int a Class B Need to access
  • 通过 NHibernate 进行查询,无需 N+1 - 包含示例

    我有一个 N 1 问题 我不知道如何解决它 可以在这个问题的底部找到完全可重复的样本 因此 如果您愿意 请创建数据库 设置 NUnit 测试和所有附带的类 并尝试在本地消除 N 1 这是我遇到的真实问题的匿名版本 众所周知 这段代码对于帮助
  • 将构建日期放入“关于”框中

    我有一个带有 关于 框的 C WinForms 应用程序 我使用以下方法将版本号放入 关于 框中 FileVersionInfo GetVersionInfo Assembly GetExecutingAssembly Location F
  • 在 C 中使用 GNU automake 中的解析器

    我是 GNU autotools 的新手 在我的项目中使用了 lex 和 yacc 解析器 将它们作为 makefile am 中的源代码会产生以下错误 配置 in AC CHECK PROGS YACC bison yacc none i
  • 在类的所有方法之前运行一个方法

    在 C 3 或 4 中可以做到这一点吗 也许有一些反思 class Magic RunBeforeAll public void BaseMethod runs BaseMethod before being executed public
  • 什么是 __declspec 以及何时需要使用它?

    我见过这样的例子 declspec在我正在阅读的代码中 它是什么 我什么时候需要使用这个构造 这是 Microsoft 对 C 语言的特定扩展 它允许您使用存储类信息来赋予类型或函数属性 文档 declspec C https learn
  • 使用 C# 从 DateTime 获取日期

    愚蠢的问题 给定日期时间中的日期 我知道它是星期二 例如我如何知道它的 tue 2 和 mon 1 等 Thanks 您正在寻找星期几 http msdn microsoft com en us library system datetim
  • 用于 C# XNA 的 Javascript(或类似)游戏脚本

    最近我准备用 XNA C 开发另一个游戏 上次我在 XNA C 中开发游戏时 遇到了必须向游戏中添加地图和可自定义数据的问题 每次我想添加新内容或更改游戏角色的某些值或其他内容时 我都必须重建整个游戏或其他内容 这可能需要相当长的时间 有没
  • 带重定向标准流的 C# + telnet 进程立即退出

    我正在尝试用 C 做一个 脚本化 telnet 项目 有点类似于Tcl期望 http expect nist gov 我需要为其启动 telnet 进程并重定向 和处理 其 stdin stdout 流 问题是 生成的 telnet 进程在
  • Googletest:如何异步运行测试?

    考虑到一个包含数千个测试的大型项目 其中一些测试需要几分钟才能完成 如果按顺序执行 整套测试需要一个多小时才能完成 通过并行执行测试可以减少测试时间 据我所知 没有办法直接从 googletest mock 做到这一点 就像 async选项

随机推荐