如何为 Silverlight 编译 C++/CLI 代码?

发布于 2024-10-03 03:34:40 字数 273 浏览 3 评论 0原文

我有一个 C++/CLI 库,我想在 Silverlight 应用程序中使用它。应该可以用任何 .NET 语言为 Silverlight 编写代码,但到目前为止我只弄清楚了如何编译 C#。 Silverlight 似乎无法使用为 .NET 编译的 DLL。

我正在使用 Visual Studio 2010 和 Silverlight 4。Silverlight 唯一可用的新项目是 C# 项目。将代码移植到 C# 并不是一个实际的选择。

如何为 Silverlight 编译 C++/CLI 代码?

I have a C++/CLI library that I would like to use in a Silverlight application. It is supposed to be possible to write code for Silverlight in any .NET language, but so far I've only worked out how to compile C#. Silverlight does not seem to be able to use DLLs compiled for .NET.

I'm using Visual Studio 2010 and Silverlight 4. The only new projects available for Silverlight are C# projects. Porting the code to C# is not a practical option.

How do I compile C++/CLI code for Silverlight?

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

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

发布评论

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

评论(5

雨后彩虹 2024-10-10 03:34:40

我想我可能已经获得了一个 VS2010 C++/CLI 类库项目来构建(仅)Silverlight 程序集的引用。

更新

好吧,这是可能的。但这并不

首先,您必须使用未记录的编译器开关说服 C++ 编译器不加载 .NET Framework。但这还不是最糟糕的部分。

  • 将您的 C++/CLI 项目“公共语言运行时支持”设置为 /clr:safe
  • 接下来,在“引用”下,删除所有引用。
  • 接下来,在 C++/CLI 项目属性中,在 C++ > 下命令行,输入 /d1clr:nomscorlib /FU"C:\Program Files (x86)\Microsoft Silverlight\4.0.50917.0\mscorlib.dll"
  • 现在,保存项目并退出 Visual Studio 。在文本编辑器中打开 .vcxproj,然后更改框架版本设置。您希望它与 C# Silverlight 项目相同:

    Silverlight
    v4.0
    $(TargetFrameworkVersion)

  • 现在,重新打开 Visual Studio,并生成项目。您会收到错误消息,因为编译器使用 #using 自动生成文件,并且搜索路径首先找到 .NET Framework 版本。

    Silverlight,Version=v4.0.AssemblyAttributes.cpp(1):致命错误 C1197:无法引用“c:\windows\microsoft.net\framework\v4.0.30319\mscorlib.dll”作为程序已经引用了 'c:\program files (x86)\microsoft silverlight\4.0.50917.0\mscorlib.dll'

  • 双击错误以打开自动生成的文件。将无路径引用替换为例如(这是放置引用的位置,而不是在项目属性中)

    #using

    #using

    #using

  • 幸运的是,编译器将您的更改保留在原处。因此,只要没有人清理您的临时目录,您就应该表现良好。

  • 现在构建应该成功了。

然后,您需要将 C++/CLI 项目创建的 DLL 添加到您的 Silverlight 应用程序中。请注意,您无法设置项目引用,因为 VS2010 仍然不确信 C++/CLI 是 Silverlight 项目。因此,您必须浏览引用并将其添加为程序集文件。 (并且它不会自动在 Debug 和 Release 之间切换以匹配 Silverlight 应用程序)。

最后的注释

我让它在调试模式下运行一个空的 Silverlight 应用程序,并在 C++/CLI 代码中间的断点处停止。此外,C++/CLI 代码成功地将值返回给 C#,并且 C# 中的局部变量收到了正确的值。所以我想它正在发挥作用。

我尝试了更多步骤来完成这项工作,但我认为它们不会影响结果。不过,如果您遇到错误,请告诉我,我会尽力找出我在这个答案中遗漏的内容。

I think I may have gotten a VS2010 C++/CLI class library project to build with references to (only) Silverlight assemblies.

Update

Ok, it is possible. But it is not nice.

First, you must convince the C++ compiler to NOT load the .NET Framework, using an undocumented compiler switch. But that's not the worst part.

  • Set your C++/CLI project "Common Language Runtime Support" to /clr:safe
  • Next, under References, remove all references.
  • Next, in the C++/CLI project properties, under C++ > Command Line, enter /d1clr:nomscorlib /FU"C:\Program Files (x86)\Microsoft Silverlight\4.0.50917.0\mscorlib.dll"
  • Now, save the project and exit Visual Studio. Open the .vcxproj in a text editor, and change the framework version setting. You want it to be the same as a C# Silverlight project:

    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>

  • Now, reopen Visual Studio, and build the project. You'll get an error because the compiler auto-generated a file with #using<mscorlib> and the search path finds the .NET Framework version first.

    Silverlight,Version=v4.0.AssemblyAttributes.cpp(1): fatal error C1197: cannot reference 'c:\windows\microsoft.net\framework\v4.0.30319\mscorlib.dll' as the program has already referenced 'c:\program files (x86)\microsoft silverlight\4.0.50917.0\mscorlib.dll'

  • Double-click the error to open the auto-generated file. Replace the path-less reference with e.g. (here's where you put your references, not in the project properties)

    #using <c:\program files (x86)\microsoft silverlight\4.0.50917.0\mscorlib.dll>

    #using <c:\program files (x86)\microsoft silverlight\4.0.50917.0\System.dll>

    #using <c:\program files (x86)\microsoft silverlight\4.0.50917.0\System.Core.dll>

  • Luckily, the compiler leaves your changes in-place. So you should be good as long as no one cleans your temp directory.

  • Building should now succeed.

Then, you need to go add the DLL created by the C++/CLI project to your Silverlight application. Note that you can't set up a project reference, because VS2010 still isn't convinced that the C++/CLI is a Silverlight project. So you'll have to browse and add the reference as an assembly file. (And it won't automatically switch between Debug and Release to match the Silverlight application).

Final Notes

I got it to run an empty Silverlight application in Debug mode and stop at a breakpoint in the middle of C++/CLI code. Also the C++/CLI code successfully returned a value to C# and the local variable in C# received the correct value. So I guess it's working.

I went through a bunch more steps trying to make this work, but I don't think they affected the outcome. If you run into errors, though, let me know and I'll try to figure out what I omitted from this answer.

メ斷腸人バ 2024-10-10 03:34:40

Ben Voigt,谢谢你,它对我也有用。

另外,如果您的 C++ 代码执行了 C++ 语言特有的任何操作(即不完全是 IL 可移植的),例如对数组使用堆栈语义,您将收到以下错误:

could not find assembly 'Microsoft.VisualC.dll' etc.

如果您使用完整的 .NET Framework 重新编译,然后转储在 IL 代码中,您将找到对“''.$ArrayType$$$BY06$$CB_W modopt”或类似内容的引用。这会告诉您在哪里更改代码。

我发现在安装 Silverlight SDK 并将其添加到“\Program Files(x86)\Reference Assemblies”后,我不必执行 Ben Voigt 的所有步骤,只需更改项目文件就足够了。

另请注意,您还可以使用:

<TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>

如果您想针对 Windows Phone(首先安装 SDK)。

Ben Voigt, thanks for this, it worked for me too.

Also, if your C++ code does anything that is specific to the C++ language (i.e. not entirely IL portable) like using stack semantics for an array, you'll get the following error:

could not find assembly 'Microsoft.VisualC.dll' etc.

If you recompile with the full .NET Framework and then dump the IL code, you'll find references to "''.$ArrayType$$$BY06$$CB_W modopt" or something similar. This tells you where to change the code.

I found that after I installed the Silverlight SDK and it got added to "\Program Files(x86)\Reference Assemblies" I did not have to go through all of Ben Voigt's steps, just changing the project file was enough.

Another note, you can also use:

<TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>

if you want to target Windows Phone (install the SDK first).

半世蒼涼 2024-10-10 03:34:40

出于安全考虑,Silverlight 不支持本机 C++ 库,也不支持任何 P/Invoke 方案。如果您的库是纯 .Net,您也许可以使用 ILDASM 对其进行反编译,并使用 ILASM 重新编译 Silverlight。

Silverlight does not support native C++ libraries, nor any P/Invoke scenarios due to security concerns. If your library is pure .Net you might be able to decompile it with ILDASM and recompile for Silverlight with ILASM.

黎歌 2024-10-10 03:34:40

Silverlight并不是像.NET那样与操作系统紧密集成的强大开发平台。首先silverlight应该运行在任何操作系统上,所以silverlight中没有任何地方可以选择Native API。

Silverlight也不完全支持MSIL,因此在IL级别编译和重新编译它存在很多问题。

您能详细说明一下您拥有哪种 C++/CLI 代码吗?大多数富互联网应用程序(Silverlight 的目标)不包含任何强大的计算功能,而是简单的 HTML+JS 替代品。对于强大的图形,您可以使用 Silverlight 的 PixelShadder 支持。

Reflector

您还可以做的是,
将您的 C++/CLI 编译为常规 .NET DLL,使用 Reflector 从您的 dll 反汇编并生成 C# 源代码,它可能并不完美,但您将把大部分逻辑转换回 C#。

Silverlight is not a powerful development platform like .NET which is tightly integrated with operating system. First of all silverlight is supposed to run on any operating system, so there is no choice of Native API anywhere in silverlight.

Silverlight also does not support MSIL completely, so there is lot of problem in compiling and recomiping it at IL level.

Can you say more about what kind of C++/CLI code you have? Most Rich internet applications (Silverlight's target) do not include any of high powerful computation, instead they are plain simple HTML+JS alternatives. For powerful graphics, you can use Silverlight's PixelShadder support.

Reflector

What you can do alternatively is,
Compile your C++/CLI to regular .NET DLL, use Reflector to disassemble and generate C# source code from your dll, it may not be perfect, but you will have most of your logic converted back in C#.

℡Ms空城旧梦 2024-10-10 03:34:40

我能够使用 Ben Voigt 的解决方案来处理 Visual Studio 2013 中的一些细微更改
这是我所做的不同之处。

  • 卸载要在其中引用它的 silverlight 项目。右键单击并选择编辑project.csproj
  • 复制目标框架设置。对我来说这是

    <块引用>

    Silverlight;
    v5.0
    $(TargetFrameworkVersion)
    
  • 对于编译器开关 /d1clr:nomscorlib 这对我不起作用。此外,对 silverlight 的 mscorlib 的引用会自动添加到编译的输出中,而无需在命令行选项中指定。这就是我解决这个问题的方法。

  • Just Deompile中打开项目

  • 加载程序集编辑器插件

  • 在树中导航到引用

  • 从 reflexil 菜单中删除对非 silverlight mscorlib 的引用。

  • 右键单击组件树的顶层,并在 reflexil 菜单下另存为。

我还没有测试所有的功能,但到目前为止我测试过的功能都按预期工作。

谢谢你,本,你的帖子节省了我很多时间。我想我必须移植我的图书馆:)

I was able Ben Voigt's solution to work with some minor changes in Visual Studio 2013
Here is what I did different.

  • Unload the silverlight project that you want to reference it in. Right click and choose edit project.csproj
  • Copy the Target Framework Settings. For me this was

    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
    
  • For the compiler switch /d1clr:nomscorlib This was not working for me. Also a reference to mscorlib for silverlight was automatically added to the complied output without specifying it on the command line options. This is how I got around it.

  • Open the project in Just Deompile

  • Load the Assembly Editor Plugin

  • Navigate the tree to the references

  • Delete the reference to the non silverlight mscorlib from the reflexil menu.

  • Right click on the top level of the tree for the assembly, and save as under the reflexil menu.

I haven't tested all of the functions, but the ones I have tested so far worked as expected.

Thank you Ben, your post has saved me a lot of time. I was thinking I was going to have to port my library:)

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