繁体   English   中英

在C ++中使用C#作为脚本语言

[英]Using C# as scripting language in C++

我试图将C#作为脚本语言嵌入到我的C ++库中。 我知道这可能不是一项微不足道的任务,所以我去了一个最小的测试项目,看看这是否可能首先。

我设法创建了一个C#程序集,其中包含用于管理简单脚本的代码,并使用CSharpCodeProvider运行时编译它们。 使用C#console app作为测试项目测试程序集(给定C#源文件在内存中编译并在必要时执行)。

因此,下一步是将其与C ++应用程序联系起来。

我已经设法使用COM做到了这一点。 我将C#dll,类和接口导出为COM对象,并使用Regasm生成tlb文件。

我能够在C ++项目中创建这些类的实例并调用它们的方法,一切似乎都能正常工作(例如显示Windows.Forms消息框),直到需要执行实际逻辑。 它只会抛出不应抛出的异常,因为它已经与C#控制台应用程序一起作为库的主机。

因为我不知道我是否可以调试COM组件(很好地踩到这个C#dll的代码是不可能的AFAIK)所以我添加了大量的消息框和try-catch块。

当我尝试从编译的程序集中检索任何类型时,它似乎会中断。 它抛出: Reflection.ReflectionTypeLoadException

另一方面,编译不会失败也不会生成任何错误消息。

使用C#触发这些方法可以100%工作,只有在从C ++执行时才会以某种方式中断。

可能是什么原因造成的? 或者可能还有另一种方法可以做我想做的事情? 我发现COM在某种程度上适合在这种情况下使用,但有哪些方面,我不知道这导致这样的代码打破?

编辑:这是作为COM导出的托管C#程序集: http//nopaste.info/9da70dbcbd.html

所以这些对象可以从C ++ app访问,如下所示: http//nopaste.info/50c4c9726a.html

并且脚本就像从IScript派生的类一样简单,并实现显示消息框的Execute方法。

编辑2:

有关抛出的异常的详细信息如下:“无法加载文件或程序集'lame2.scripting,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = 84d0df983ded76a1'或其中一个依赖项.Niemożnaodnaleźćokreślonegopliku。”

最后一句意味着无法找到文件。

但是很奇怪,因为编译时我有以下行:compilerparams.ReferencedAssemblies.Add(“D:\\ Interop \\ lame2.scripting \\ lame2.scripting \\ bin \\ Debug”+“\\ lame2.scripting.dll”);

这是“脚本”内容:

using System;
using System.Linq;
using System.Windows.Forms;
using System.Reflection;
using lame2.scripting;

namespace Olaboga
{
  public class TestScript : IScript
  {
    public TestScript() { }

    public void Execute(Event ev)
    {
      MessageBox.Show("Script that has been compiled from a source file has been invoked.   TestScript.Execute");
    }
  }
}

编辑3:

最后,从内存中的编译切换到编译到临时文件后,它突然开始正常工作。 所以最后一个问题可能有人知道为什么它在内存中编译时无法工作,如果可以的话。

如果您可以将应用程序功能公开为COM对象模型,则应该可以执行此操作。 您应该注意以.NET互操作层可以正确处理的方式建模接口。

如果我理解正确,你在调试从C#脚本生成的.NET程序集时遇到问题,对吗? 在这种情况下,您可以在编译程序集时使用以下编译器设置:

CompilerParameters cp = new CompilerParameters();

// Generate debug information.
cp.IncludeDebugInformation = true;

// Save the assembly as a physical file.
cp.GenerateInMemory = false;

// Set a temporary files collection. 
// The TempFileCollection stores the temporary files 
// generated during a build in the current directory, 
// and does not delete them after compilation.
cp.TempFiles = new TempFileCollection(".", true);

这将启用生成代码的调试,就像您拥有源代码,调试符号和程序集一样。 但是,你提到'COM组件'几次,但我没有看到 - 有一个C ++应用程序和.NET程序集 - 介于两者之间的东西不是真正的COM组件,而是'interop magic',或多或少,只是整理这两方之间的东西。

如果在调试包含实现的原始.NET程序集时遇到问题,请确保调试设置正确:

  • 如果您使用本机应用程序正常开始调试(F5),请转到Project Settings -> Debugging -> Debugger Type并将其设置为Mixed
  • 如果将调试器附加到正在运行的进程,请在“ Attach to Process表单中单击“附加到”文本框附近的“ Select...按钮,然后选择所需的那些(托管和本机)

这假定您确实拥有程序集的源代码和.pdb文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM