为非托管代码提供托管控制句柄 - 访问冲突
所以我有一个第三方提供的SDK,用于从远程源观看流媒体视频。远程源运行第三方提供的服务器来捕获和存储视频,我可以连接到该服务器并通过 SDK 获取视频。我通过 COM 引用 SDK,基本的非图形操作(例如连接到服务器、选择视频源等)都运行良好。
问题是,使用此 SDK 向用户实际显示视频的主要(唯一)方法是将 hWnd(作为 int)传递到一个方法中,然后该方法会将视频异步绘制到该窗口的客户区域上。据我所知,这里的“窗口”具有 GUI 窗口的含义,在 .NET 术语中,它是任何带有窗口句柄的 WinForms 控件。就我而言,我使用 PictureBox 控件(用户希望看到的每个提要一个)。
问题是我显然不能将托管 PictureBox 控件的句柄放入此 SDK 方法中,因为当我这样做时,我会从非托管线程收到 AccessViolationException。我正在编写一个用 VB 6 编写的示例程序(它在我的计算机上针对测试服务器运行),它对 VB PictureBox 执行相同的操作,并且工作得很好,但显然无论 SDK 试图做什么我们漂亮的安全.NET 沙箱对象不会随 CLR 一起飞行。
帮助?我希望我可以提供更多信息或代码示例,但我无法提供任何足够干净的内容以使其在一般情况下都能工作,而且我不能透露正在使用的 SDK。我认为我需要的只是告诉 .NET 我引用的代码应该被信任来对窗口执行它想要的操作,或者以某种方式将窗口移动到我的程序舒适的沙箱之外管理较少的内存空间。
编辑:好的,已经取得了一些进展。我现在正在验证是否已使用 IsHandleCreated 创建控件的句柄,然后再将句柄提供给该方法。然而,正如 Hans Passant 所说,IntPtr 不是 int。那么,如何将这个方钉安装到圆孔中呢?我尝试过 ToInt32() 函数和显式转换为 (int) 。即使在为 32 位架构编译我的库时,这两种方法都不起作用。我是否应该回到第三方并说他们的 SDK 是 POS,不让我传递指针?
So I have this SDK provided by a third party which is used for viewing streaming video from a remote source. The remote source runs a server provided by the third party that captures and stores video, and I can connect to that server and get video via the SDK. I am referencing the SDK via COM, and basic nongraphical operations like connecting to the server, selecting a video feed etc are all working just fine.
The problem is that the main (only) method for actually showing video to the user using this SDK is to pass an hWnd (as an int) into a method that will then asynchronously paint the video onto the client area of that window. "Window" here, to my knowledge, has the meaning of a GUI window, which in .NET terms would be any WinForms control with a window handle. In my case, I'm using PictureBox controls (one per feed the user wishes to see).
The problem is that I apparently cannot just drop a managed PictureBox control's handle into this SDK method, because when I do so I receive an AccessViolationException from the unmanaged thread. I'm working off of an example program written in VB 6 (which works on my computer against a test server) which does the same thing with a VB PictureBox, and that works just fine, but apparently whatever the SDK is trying to do to our nice safe .NET sandbox objects is not flying with the CLR.
Help? I wish I could give more information or a code sample, but I can't provide anything sanitized enough that it would work in the general case and I can't divulge the SDK being used. I think that what I need is simply to tell .NET that my referenced code should be trusted to do what it wants with the window, OR to somehow move the window to an less-managed memory space outside my program's comfy sandbox.
EDIT: OK, a little progress has been made. I am now verifying that the handle for the control has been created using IsHandleCreated, before giving the handle to the method. However, as Hans Passant said, an IntPtr is not an int. So, how do I fit this square peg in the round hole? I have tried both the ToInt32() function and an explicit cast to (int). Neither works, even when compiling my library for 32-bit architecture. Do I go back to the third party and say their SDK is a POS for not letting me pass a pointer?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这应该可以正常工作。 Windows 窗体控件的
Control.Handle
只是 Windows API 中的标准 HWND。许多 DirectX 示例都使用这种精确技术。话虽如此,请确保在创建控件之前不会将其传递到本机代码中。例如,如果您在表单的构造函数期间(加载之前)传递句柄,则该句柄此时将无效。
This should work fine. A
Control.Handle
for a windows forms control is just a standard HWND from the Windows API. Many DirectX samples use this exact technique.That being said, make sure this isn't passed into the native code until after the control is created. If you pass the handle during a form's constructor (prior to Load), for example, the Handle will be invalid at that point.