我正在尝试将 C# 作为脚本语言嵌入到我的 C++ 库中。我知道这可能不是一项微不足道的任务,所以我首先进行了一个最小的测试项目,看看这是否可能。
我设法创建了一个 C# 程序集,其中包含用于管理简单脚本并在运行时使用CSharpCodeProvider
. 该程序集使用 C# 控制台应用程序作为测试项目进行了测试(假设 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++ 应用程序访问的,如下所示:http: //nopaste.info/50c4c9726a.html
并且脚本就像类派生IScript
和实现Execute
显示消息框的方法一样简单。
编辑2:
有关引发的异常的详细信息如下:“无法加载文件或程序集 'lame2.scripting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=84d0df983ded76a1' 或其依赖项之一。Nie można odnaleźć określonego pliku。”
最后一句表示找不到文件。
但这很奇怪,因为在编译时我有以下行: 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:
最后从内存编译切换到编译到临时文件后,它突然开始正常工作。所以最后一个问题有人可以知道为什么它在内存中编译时无法工作,是否可以这样做。