只是想知道c ++或者c#中是否有任何内置函数可以让你在运行时使用编译器?例如,如果我想翻译:
!print "hello world";
成:
MessageBox.Show("hello world");
然后生成一个exe,然后才能显示上面的消息?几年前我在网上看过一些示例项目,但是找不到它了。
答案 0 :(得分:15)
可以使用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;
}
答案 1 :(得分:5)
在C ++中,您无法在运行时使用编译器,但可以在项目中嵌入解释器,例如CINT.
答案 2 :(得分:3)
您总是可以用脏的方式,使用system()并调用编译器“gcc ...”或等效的
答案 3 :(得分:1)
尼克的建议很好,但有一种替代方案可能更容易实施(但可能不适合所有项目)。如果您可以假设您的用户安装了编译器,您可以生成一个文件,然后使用他们的编译器进行编译。
答案 4 :(得分:1)
.NET框架提供了一些类,使您可以访问C#和VB.NET的编译器和代码生成器,从而导致程序集加载到内存或简单的.exe文件中。请参阅CSharpCodeProvider和this article。
或者,您可以创建源文件并将其手动(命令行调用(system
)编译到编译器,makefile)。
关于源代码的翻译:你必须在这里使用像正则表达式这样的解析机制,或者使用像Coco / R,yacc等编译器编译工具。(注意,在C ++下,boost::spirit
可以也很有用)
答案 5 :(得分:1)
在C#中,您可以创建一个.NET“CodeDom”树,然后使用.NET编译器对其进行编译。这使您可以完全访问.NET的大多数功能。
有关详细信息,请参阅“System.CodeDom”命名空间或MSDN help for CodeCompileUnit。