HOWTO:从非托管 C# 调用托管 C# 接口 在 WindowsCE 紧凑框架上

发布于 2024-07-20 11:21:50 字数 1354 浏览 4 评论 0原文

我有大量的非托管 Windows CE 5 C++ 代码,它提供了一个我想在新产品中使用的 UI,方法是将其与在 Windows CE 6 和 Compact Framework 上用托管 C# 编写的大量更新的业务和通信逻辑相结合。

UI 可能了解业务逻辑,但我希望业务逻辑不了解 UI,以便稍后可以将其替换为托管版本或我选择作为前端的任何其他 UI。

我发现一篇文章描述了如何使用COM作为Windows世界中的桥梁,但是我在WinCE下的.NET CF中应用它时遇到了困难。 过去,我导入类型库并使用 COM 调用(CoInitialize()、CoCreateInstance())来获取指向其他 Windows 平台上的接口的指针,这就是我目前所追求的策略:直接在非托管 C++ 库来访问托管库中的 C# 接口,假设 WinCE 中提供了相同的功能。

这是我的问题:类型库。 它无法从我的托管 C# 库中获得,因为我过去通过“#import“SomeCPPLibrary.dll””语句使用过它。 我相信它隐藏在 .dll 程序集中,以与过去不同的方式存储,因此不能通过库本身的 #import 直接使用。 我认为我可以 #import a typelib,但我找不到从托管 .dll 中提取 typelib 的方法,虽然我可能能够将接口定义文件 (.idl) 组合在一起并使用平台的 midl.exe要从中生成 .tlb,无法保证我的 .idl 以及由此产生的 .tlb 与我的 C# .dll 中的内容真正匹配。 我什至不知道平台 midl.exe 是否以这种方式工作,但假设它确实如此。

  1. 我是不是找错树了? 是否可以通过相应的 COM 接口在非托管 C++ 中使用托管 C# 接口?

  2. 在其 AssemblyInfo.cs 文件中设置 [程序集:ComVisible(true)] 属性是否可以通过 AssemblyInfo.cs 定义的 GUID 在非托管世界中通过 COM 提供托管程序集中的所有接口,或者我是否必须这样做更多内容?

  3. 如何从托管 .dll 中获取类型库,以便我的非托管 C++ 库可以#导入它?

    如何
  4. 我尝试将托管 C# 库项目添加为非托管 C++ 库项目中的引用,但这似乎没有帮助。 在这种情况下,这样的引用是否相关?

  5. 是否有更好的方法来解决从非托管 C++ 世界调用托管 C# 代码的基本问题? 我刚刚在这里读到的是一个混合模式库,带有托管翻译层,以弥合非托管/托管差距。 我不确定这是一个好的策略,因为呼叫响应速度是一个重要因素,但从长远来看,它可能会更好,因为我计划在某个时候将 UI 重写为托管 C#,从而将所有精力都放在抛弃用户界面而不是破坏更持久的业务/通信逻辑? 不管这个问题的答案如何,如果只是出于好奇,我仍然想解决使用 COM 的问题。

I have extensive unmanaged Windows CE 5 C++ code that provides a UI that I want to use in a new product by combining it with a large amount of newer business and communications logic written in managed C# on Windows CE 6 and the Compact Framework.

The UI may know about the business logic, but I want the business logic ignorant of the UI such that I can later replace it with a managed version, or any other UI that I choose as a front-end.

I found an article that describes how to use COM as the bridge in the Windows world, but I'm having difficulty applying it in the .NET CF under WinCE. In the past, I've imported type libraries and used COM calls (CoInitialize(), CoCreateInstance()) to obtain pointers to interfaces on other Windows platforms, and that's the strategy I'm pursuing at the moment: using COM directly in the unmanaged C++ library to access the C# interfaces in my managed library, assuming that the same facility is provided in WinCE.

Here's my problem: the typelib. It's not available from my managed C# library as I've used it in the past via a '#import "SomeCPPLibrary.dll"' statement. I believe it's buried in the .dll assembly, stored in a different manner than it has been in the past and hence, not directly available through a #import of the library itself. I think that I can #import a typelib, but I cannot find a way to extract the typelib from my managed .dll, and while I might be able to hack together an interface definition file (.idl) and use the platform's midl.exe to generate a .tlb from it, there's no guarantee that my .idl, and hence, resulting .tlb, would really match what is in my C# .dll. I don't even know if the platform midl.exe works in this manner but assume that it does.

  1. Am I barking up the wrong tree? Is it possible to use a managed C# interface in unmanaged C++ through a corresponding COM interface?

  2. Does setting the [assembly: ComVisible(true)] attribute in its AssemblyInfo.cs file make all interfaces in the managed assembly available through COM in the unmanaged world via the GUID the AssemblyInfo.cs defines, or do I have to do something more?

  3. How do I get the typelib out of the managed .dll so that my unmanaged C++ library can #import it?

  4. I tried adding my managed C# library project as a reference in the unmanaged C++ library project, but that didn't seem to help. Is such a reference relevant at all in this situation?

  5. Is there a better approach to solving the basic problem of calling managed C# code from the unmanaged C++ world? Something I just read about here is a mixed mode libarary with a managed translation layer to bridge the unmanaged/managed gap. I'm not sure that is a good strategy as call response speed is an important factor, but might it be better in the long run as I plan to rewrite the UI to managed C# at some point, and thus puts all the effort on the throw-away UI rather than mucking with the more permanent business/comms logic? Regardless of the answer to this question, I'd still like to solve the problem of using COM, if for no other reason than curiosity.

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

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

发布评论

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

评论(2

爱本泡沫多脆弱 2024-07-27 11:21:50

我尝试在 WinCE 中从 C++ 调用 C#。 我不相信 Compact Framework 提供任何 COM 支持,因此您不能使用 ComVisible(true)。

我也找不到在 C++ 中托管 .NET 的方法,因为该功能同样没有在 Compact Framework 中公开。

我的解决方案是创建一个存根 C# 应用程序并通过消息队列与 C++ 主机通信。 这也解决了数据编组问题。 就我的使用而言,性能还不错。 最大的成本是存根的启动时间,如果您的完整应用程序是 C# 的,那么无论如何您都必须支付该时间。

I have attempted to call C# from C++ in WinCE. I don't believe there is any COM support provided by the Compact Framework, so you can't use ComVisible(true).

I also couldn't find a way to host .NET in C++ because again the functionality wasn't exposed in the Compact Framework.

My solution was to create a stub C# application and communicate with the C++ host via Msg Queues. This also solves the data marshaling issue. Performance for my usage is fine. The biggest cost is the startup time of the stub which you'd have to pay anyway if you're complete app was C#.

絕版丫頭 2024-07-27 11:21:50

你找错了树。 为了使本机代码调用托管代码,本机代码必须启动 CLR 的执行引擎。 这称为 CLR 托管,并且在CF。 这意味着你根本无法做到这一点——即使有创造性的黑客技术也做不到(相信我,我已经在每条巷子里尝试过)。

You're barking up the wrong tree. In order for native code to call into managed code, the native code has to spin up the CLR's execution engine. This is known as CLR Hosting, and it isn't supported in the CF. This means that you simply can't do it - not even with creative hacking (trust me, I've been down every alley trying).

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