【发布时间】:2009-09-01 11:32:08
【问题描述】:
只是想知道在 c++ 或 c# 中是否有任何内置函数可以让您在运行时使用编译器?例如,如果我想翻译:
!print "hello world";
进入:
MessageBox.Show("hello world");
然后生成一个可以显示上述信息的exe?几年前我在网上看到过这样的示例项目,但现在找不到了。
【问题讨论】:
标签: c# c++ compiler-construction messagebox
只是想知道在 c++ 或 c# 中是否有任何内置函数可以让您在运行时使用编译器?例如,如果我想翻译:
!print "hello world";
进入:
MessageBox.Show("hello world");
然后生成一个可以显示上述信息的exe?几年前我在网上看到过这样的示例项目,但现在找不到了。
【问题讨论】:
标签: c# c++ compiler-construction messagebox
可以使用 C#。看看这个来自 CodeProject 的Sample Project。
代码提取
private Assembly BuildAssembly(string code)
{
Microsoft.CSharp.CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeCompiler compiler = provider.CreateCompiler();
CompilerParameters compilerparams = new CompilerParameters();
compilerparams.GenerateExecutable = false;
compilerparams.GenerateInMemory = true;
CompilerResults results = compiler.CompileAssemblyFromSource(compilerparams, code);
if (results.Errors.HasErrors)
{
StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
foreach (CompilerError error in results.Errors )
{
errors.AppendFormat("Line {0},{1}\t: {2}\n", error.Line, error.Column, error.ErrorText);
}
throw new Exception(errors.ToString());
}
else
{
return results.CompiledAssembly;
}
}
public object ExecuteCode(string code, string namespacename, string classname, string functionname, bool isstatic, params object[] args)
{
object returnval = null;
Assembly asm = BuildAssembly(code);
object instance = null;
Type type = null;
if (isstatic)
{
type = asm.GetType(namespacename + "." + classname);
}
else
{
instance = asm.CreateInstance(namespacename + "." + classname);
type = instance.GetType();
}
MethodInfo method = type.GetMethod(functionname);
returnval = method.Invoke(instance, args);
return returnval;
}
【讨论】:
在 C++ 中,您不能在运行时使用编译器,但可以在项目中嵌入解释器,例如 CINT.
【讨论】:
你总是可以用很脏的方式来做,使用 system() 并调用编译器“gcc...”或你的等价物
【讨论】:
Nick 的建议很好,但有一个替代方案可能更易于实施(但可能不适用于所有项目)。如果您可以假设您的用户安装了编译器,您可以生成一个文件,然后使用他们的编译器进行编译。
【讨论】:
.NET 框架提供了一些类,可让您访问 C# 和 VB.NET 的编译器和代码生成器,从而将程序集加载到内存或简单的 .exe 文件。请参阅CSharpCodeProvider 和this article。
或者,您可以只创建源文件并手动编译它们(命令行调用 (system) 到编译器,makefile)。
关于源代码的翻译:您必须在这里使用正则表达式等解析机制,或者使用 Coco/R、yacc 等编译器编译器工具。(注意,在 C++ 下,boost::spirit 也可以是很有用)
【讨论】:
在 C# 中,您可以创建一个 .NET “CodeDom”树,然后使用 .NET 编译器对其进行编译。这使您可以完全访问 .NET 的大多数功能。
有关详细信息,请参阅“System.CodeDom”命名空间或MSDN help for CodeCompileUnit。
【讨论】: