如何为 Silverlight 编译 C++/CLI 代码?
我有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我想我可能已经获得了一个 VS2010 C++/CLI 类库项目来构建(仅)Silverlight 程序集的引用。
更新
好吧,这是可能的。但这并不好。
首先,您必须使用未记录的编译器开关说服 C++ 编译器不加载 .NET Framework。但这还不是最糟糕的部分。
/clr:safe
/d1clr:nomscorlib /FU"C:\Program Files (x86)\Microsoft Silverlight\4.0.50917.0\mscorlib.dll"
现在,保存项目并退出 Visual Studio 。在文本编辑器中打开 .vcxproj,然后更改框架版本设置。您希望它与 C# Silverlight 项目相同:
现在,重新打开 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.
/clr:safe
/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.
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.
Ben Voigt,谢谢你,它对我也有用。
另外,如果您的 C++ 代码执行了 C++ 语言特有的任何操作(即不完全是 IL 可移植的),例如对数组使用堆栈语义,您将收到以下错误:
如果您使用完整的 .NET Framework 重新编译,然后转储在 IL 代码中,您将找到对“''.$ArrayType$$$BY06$$CB_W modopt”或类似内容的引用。这会告诉您在哪里更改代码。
我发现在安装 Silverlight SDK 并将其添加到“\Program Files(x86)\Reference Assemblies”后,我不必执行 Ben Voigt 的所有步骤,只需更改项目文件就足够了。
另请注意,您还可以使用:
如果您想针对 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:
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:
if you want to target Windows Phone (install the SDK first).
出于安全考虑,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.
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#.
我能够使用 Ben Voigt 的解决方案来处理 Visual Studio 2013 中的一些细微更改
这是我所做的不同之处。
复制目标框架设置。对我来说这是
<块引用>
对于编译器开关
/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.
Copy the Target Framework Settings. For me this was
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:)