动态编译_动态编译c#代码时,首次执行代码很慢,如何解决? - CSDN
精华内容
参与话题
  • java实现动态编译的几种方法

    千次阅读 2018-09-19 09:31:57
    所谓动态编译,就是在程序运行时产生java类,并编译成class文件。    在D盘test目录下有两个java文件:AlTest1.java、AlTest2.java,现需要通过java代码实现java文件到class文件的编译操作: import java.io....

    所谓动态编译,就是在程序运行时产生java类,并编译成class文件。

     

     在D盘test目录下有两个java文件:AlTest1.java、AlTest2.java,现需要通过java代码实现java文件到class文件的编译操作:

    
    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    
    import javax.tools.JavaCompiler;
    import javax.tools.ToolProvider;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.piao.main.ApplicationAdmin;
    
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ComponentScan("com.piao")
    @SpringBootTest(classes = ApplicationAdmin.class)
    public class Compiler {
    	
    	@Test
    	public void compiler1(){
    		String javaAbsolutePath = "D:/test/AlTest1.java";
    		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    		compiler.run(null, null, null, "-encoding", "UTF-8", "-classpath", javaAbsolutePath.toString(), javaAbsolutePath);
    	}
    	@Test
    	public void compiler2(){
    		String javaAbsolutePath = "D:/test/AlTest2.java";
    		
    		try {
    			Process process = Runtime.getRuntime().exec("javac -classpath D:/test/ " + javaAbsolutePath);
    			InputStream errorStream = process.getErrorStream();
    			InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
    			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    			String line = null;
    			while ((line=bufferedReader.readLine()) != null){
    				System.out.println(line);
    			}
    			int exitVal = process.waitFor();
    			System.out.println("Process exitValue: " + exitVal);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}	
    	}
    	
    	 
    }
    

     运行后, D:\test 目录会生成两个class文件

     

    其中方法compiler1是使用jdk自带的rt.jar中的javax.tools包提供的编译器

    方法compiler2是使用Runtime执行javac命令

     

     

     

     

     

     

     

     

     

     

     

     

    参考资料:

    https://www.cnblogs.com/anai/p/4269858.html

    展开全文
  • Java动态编译和动态加载详解

    千次阅读 2018-10-15 13:58:43
    动态编译 在某些情况下,我们需要动态生成java代码,通过动态编译,然后执行代码。JAVA API提供了相应的工具(JavaCompiler)来实现动态编译。 //获取JavaCompiler JavaCompiler compiler = ToolProvider....

    一.动态编译

    在某些情况下,我们需要动态生成java代码,通过动态编译,然后执行代码。JAVA API提供了相应的工具(JavaCompiler)来实现动态编译。

    //获取JavaCompiler JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

    //获取java文件管理类 StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);

    //获取java文件对象迭代器 Iterable<? extends JavaFileObject> it = manager.getJavaFileObjects(files);

    //设置编译参数 ArrayList<String> ops = new ArrayList<String>(); ops.add("-Xlint:unchecked");

    //可以指定源文件或目标文件的JDK版本 ops.add("-source")/ops.add("-target");; ops.add("1.5");

    //获取编译任务:第一个null,用于输出错误的流,默认是System.err;第二个null,diagnosticListener: 编译器的默认行为 ;第三个null,classes,参与编译的class,为null时表示全部

    //JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, ops, null, it);

    //执行编译任务 task.call();

     

    动态编译几个关键类

    类名

    作用

    创建方式

    JavaCompiler

    动态编译的入口,也是基础类

    ToolProvider.getSystemJavaCompiler()

    StandardJavaFileManager

    java文件管理类

    compiler.getStandardFileManager

    Iterable

    文件对象迭代器

    manager.getJavaFileObjects(files)

    ArrayList<String> 

    编译参数

    new ArrayList<String>()

     

    踩坑记

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 这句代码在IDEA中运行正常,然后打成jar包在桌面双击运行时得到的是null

    问题解决:

    查看ToolProvider源码可知,是因为找不到tools.jar---》将tools.jar复制到jre/lib下

     

    二.动态加载

    JAVA中的类加载:双亲委派模式

    URL  url = new URL("file:" + CLASS_PATH);

    ClassLoader  classLoader = new URLClassLoader(new URL[]{url});

    Class<?> cls = classLoader.loadClass(name);

    Method method = cls.getDeclaredMethod(String methodName)

    Object obj = cls.newInstance();

    Object result = method.invoke(Object obj, Object[] params);

     

    class.forName()和classLoader区别:

     //Class.forName(String className)  这是1.8的源码

     public static Class<?> forName(String className) throws ClassNotFoundException {

            Class<?> caller = Reflection.getCallerClass();

            return forName0(className, true, ClassLoader.getClassLoader(caller), caller);    

    }      

    //注意第二个参数,是指Class被loading后是不是必须被初始化。 不初始化就是不执行static的代码即静态代码 class.forName()前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。

    而classLoader只干一件事情,就是将.class文件加载到jvm中。

     

    扩展:TOMCAT中的类加载架构

     

    1、JAVA_HOME:设置为JDK的安装目录,如D:\java\jdk1.8。一些依赖JAVA的软件通过该环境变量来获得JDK的安装目录,如大家都知道的Eclipse、Tomcat等。

    2、PATH:在已有值最后加上 ;%JAVA_HOME%\bin ,其中;是分隔符,用于分开每个目录,其中%JAVA_HOME%则是引用上面的JAVA_HOME环境变量的值,可以直接用JDK的安装目录代替,下面的CLASSPATH类似。执行路径(也就是PATH环境变量的值)是只操作系统搜索本地可执行文件的目录列表,在shell中执行命令时,它会在执行路径中查找所对应的程序。所以在PATH中加入了%JAVA_HOME%\bin目录后,在shell中就可以执行javac或者java命令。

    3、CLASSPATH:设置值为.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; 注意其中的标点符号,其中第一个点“.”表示当前目录,而分号“;”则是分隔符。 这个CLASSPATH为JVM加载类的目录,比如HelloWorld.java中有import其他类,用javac编译时它会在CLASSPATH中去找你所import的类,如果找不到则出现编译错误。 另外在使用java时使用-classpath 参数可以指定要加载类的目录,比如命令行执行:C:/UsersJakey>java -classpath D:\temp HelloWorld  ,这样就可以当命令行在C盘时执行D盘目录中的JAVA类。

     

    展开全文
  • 动态编译

    2019-08-05 20:15:36
    动态编译的应用场景 1、可以做一个浏览器端编写java代码,上传服务器编译呵运行的在线评测系统。 2、服务器动态加载某些类文件进行编译 两种做法 一、通过Runtime调用javac,启动新的进程去操作 Runtime run =...

    动态编译的应用场景

    1、可以做一个浏览器端编写java代码,上传服务器编译呵运行的在线评测系统。

    2、服务器动态加载某些类文件进行编译

    两种做法

    一、通过Runtime调用javac,启动新的进程去操作

    Runtime run = Runtimr.getRuntime();
    
    Process process = run.exec("javac -cp d:/myjava/HelloWorld);
    
    
    /**
     * 测试java动态编译
     */
    public class Demo01 {
        public static void main(String[] args) throws IOException {
            //通过IO流操作,将字符串存储成一个临时文件,然后调用静态编译方法
            String str = "public class Hi {public static void main(String[] args){soutSystem.out.println()}}";
    
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            int result = compiler.run(null,null,null,"c:/myjava/HelloWorld.java");
            System.out.println(result==0?"编译成功":"编译失败");
    
            //通过Runtime.getRuntime()运行启动新的进程运行
            Runtime run = Runtime.getRuntime();
            Process process = run.exec("java -cp c:/myjava/ HelloWorld");
            //输入流
            InputStream in = process.getInputStream();
            //转化流
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String info = "";
            while((info=reader.readLine())!=null){
                System.out.println(info);
            }
        }
    }

    二、通过JavaCompiler动态编译

    /**
     * 测试java的动态编译
     */
    public class Demo01 {
    	public static void main(String[] args) throws Exception {
    		
    		//通过IO流操作,将字符串存储成一个临时文件(Hi.java),然后调用动态编译方法!
    		String str = "public class Hi {public static void main(String[] args){System.out.println(\"HaHa,sxt!\");}}";
    		
    		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    		int result = compiler.run(null, null, null, "c:/myjava/HelloWorld.java");
    		System.out.println(result==0?"编译成功":"编译失败");
    		
                    //通过反射运行编译好的类
    		try {
                        URL[] urls = new URL[] {new URL("file:/"+"C:/myjava/")};
                        URLClassLoader loader = new URLClassLoader(urls);
                        Class c = loader.loadClass("HelloWorld");
                        //调用加载类的main方法
                        Method m = c.getMethod("main",String[].class);
                        m.invoke(null,(Object)new String[]{});//传参数 + Object强转型
                        //由于可变参数是JDK5.0之后才有,不加Object的话
                        //m.invoke(null,new String[]{"aa","bb"})
                        //会编译成:m.invoke(null,"aa","bb"),就发生了参数个数(2)不匹配的问题。
                        //因此,必须要加上(Object)转型,避免这个问题
                        //public static void main(String[] args)
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
            }
    }

     

    展开全文
  • 动态编译C#代码

    千次阅读 2016-05-11 19:46:49
    项目开发中,有时候会使用到动态生成代码,然后根据动态生成的代码再执行相应的操作,C#提供了动态代码的编译,利用这个特性可以实现动态生成代码,然后执行代码。 直接上代码,c#版本[MenuItem("Test/...

    项目开发中,有时候会使用到动态生成代码,然后根据动态生成的代码再执行相应的操作,C#提供了动态代码的编译,利用这个特性可以实现动态生成代码,然后执行代码。
    直接上代码,c#版本

    [MenuItem("Test/CreateCodeDll")]
        public static void CreateCodeDll1()
        {
            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerParameters parameters = new CompilerParameters();
    
            parameters.GenerateExecutable = false;
            parameters.GenerateInMemory = false;
            string path = "MyCode.dll";
            parameters.OutputAssembly = path;
            parameters.ReferencedAssemblies.Add("System");
    
            string sourceFile = @"
                using System;
    
                public class MyCode
                {
                     public static int Test(int x, int y)
                     {
                         return x+y;
                     }
                 }
            ";
            CompilerResults cr = provider.CompileAssemblyFromSource(parameters, sourceFile);
    
            if (cr.Errors.Count > 0)
            {
                // Display compilation errors.
                Debug.LogError("Errors building " + sourceFile + " into " + cr.PathToAssembly);
                foreach (CompilerError ce in cr.Errors)
                {
                    Debug.LogError(ce.ToString());
                }
            }
            else
            {
                Debug.Log("编译成功");
            }
    
            Assembly ass = cr.CompiledAssembly;
            object obj = ass.CreateInstance("MyCode");
            MethodInfo method = obj.GetType().GetMethod("Test");
            object result = method.Invoke(obj, new object[] { 1, 5 });
            Debug.Log(result);
        }

    Unity脚本需要引用Unity自身的Dll类,代码如下

    [MenuItem("Test/UnityCreateDll")]
        public static void CreateDll()
        {
            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerParameters parameters = new CompilerParameters();
    
            string dllPath = EditorApplication.applicationContentsPath + "/Managed/";
            Debug.Log(EditorApplication.applicationContentsPath);
    
            parameters.WarningLevel = 2;
            parameters.GenerateExecutable = false;
            parameters.GenerateInMemory = false;
            string path = "MyCode.dll";
            parameters.OutputAssembly = path;
            parameters.ReferencedAssemblies.Add("System");
            parameters.ReferencedAssemblies.Add(dllPath + "UnityEngine");
         //   parameters.ReferencedAssemblies.Add(dllPath + "UnityEditor");
    
            string[] sourceFile = new string[] {
                Application.dataPath + "/Test1.cs",
                Application.dataPath + "/Test2.cs"
            };
    
            CompilerResults cr = provider.CompileAssemblyFromFile(parameters, sourceFile);
    
            if (cr.Errors.Count > 0)
            {
                // Display compilation errors.
                 Debug.LogError("Errors building " + sourceFile + " into " + cr.PathToAssembly);
                foreach (CompilerError ce in cr.Errors)
                {
                    Debug.LogError(ce.ToString());
                }
            }
            else
            {
                Debug.Log("编译成功");
            }
    
    
              AssetDatabase.Refresh();
        }

    这个路径是取得工程目录,也就是Assets目录的上一层目录。

    关于这里编译参数的设置见:MSDN
    warningLevel的含义见 MSDN

    展开全文
  • Java中的静态编译和动态编译

    千次阅读 2015-11-16 17:30:12
    本文是转载,很详实但也累赘。个人认为的重点在文中以粗体标注。
  • 动态编译、静态编译区别(转)

    千次阅读 2018-08-07 12:06:28
    1.静态编译:编译器在编译可执行文件时,把需要用到的对应动态链接库(.so或.ilb)中的...2.动态编译: 动态编译的可执行文件需要附带一个的动态链接库,在执行时,需要调用其对应动态链接库中的命令。所以其优点一 ...
  • java实现动态编译并动态加载

    万次阅读 2018-09-19 18:19:19
    在D盘test目录下有个java文件:AlTest.java public class AlTest { public String sayHello(){ System.out.println("AlTest类 sayHello()方法正在执行....");...现需要实现在工程已经运行过程中,进行...
  • 动态编译和静态编译

    2013-12-09 16:37:40
    静态编译就是在编译的时候把你所有的模块都编译进...动态编译就不一样了,你编译的时候那些模块都没有编译进去,一般情况下你可以把那些模块都编译成dll,这样你启动程序(初始化)的时候这些模块不会被加载,而是在运
  • 静态编译与动态编译的区别

    千次阅读 2019-04-18 21:23:28
    静态编译与动态编译的区别  动态编译的可执行文件需要附带一个的动态链接库,在执行时,需要调用其对应动态链接库中的命令。所以其优点一方面是缩小了执行文件本身的体积,另一方面是加快了编译速度,节省了系统...
  • 将C语言源代码编译动态链接库

    万次阅读 2012-02-22 23:38:12
    下面我们举一个例子,用C语言写一个简单的函数,并在控制台(命令行)中将它编译为DLL。 一、源代码 我们创建一个C语言源程序:Test.c 关键:__declspec(dllexport) 申明将这个方法导出到DLL中。 源代码...
  • QT静态编译和动态编译

    千次阅读 2016-07-25 10:18:34
    QT静态编译
  • 动态语言和静态语言的区别

    万次阅读 多人点赞 2019-05-29 16:37:46
    编译型语言和解释型语言 1、编译型语言 需通过编译器(compiler)将源代码编译成机器码,之后才能执行的语言。一般需经过编译(compile)...编译是把源代码编译成机器码, 链接是把各个模块的机器码和依赖库串连...
  • makefile编译静态库和动态

    万次阅读 2012-08-02 13:11:11
    一。静态库 创建静态库  仍使用刚才的hello.c和test.c。  第一步,生成目标文件。  gcc -c hello.c  第二步,把目标文件归档。  ar r libhello.a hello.o  file libhello.a ... gcc test.c -lhello -L....
  • 编译型和解释型的区别 先来看看编译型语言定义: 编译型语言首先是将源代码编译生成机器指令,再由机器运行机器码 (二进制)。 再来看看解释型语言的定义: 解释型语言的源代码不是直接翻译成机器指令,而是...
  • 开心一笑【年底是各种案件的高发期,我们去ATM取钱的时候,一定要注意遮挡,不要被陌生人看到你的余额,要不然啊,就,,,非常容易被人嘲笑。... 】提出问题java中的动态编译和静态编译如何理解???解
  • Linux-C动态库与静态库的编译与调用

    万次阅读 多人点赞 2020-03-10 22:38:16
    Linux-C动态库与静态库的编译与调用 一、简述 记录-Linux-C动态库与静态库的编译与调用。将实现某部分功能的代码封装成库文件,以方便调用,或者是对代码进行保护加密。应用场景:有时想将某代码提供给别人用,...
  • Linux下编译动态库及使用

    万次阅读 2018-10-10 15:38:23
    2,将一个或几个源文件编译链接,生成共享库。 3,通过 -L&lt;path&gt; -lxxx 的gcc选项链接生成的libxxx.so。 4,把libxxx.so放入链接库的标准路径,或指定 LD_LIBRARY_PATH,才能运行链接了libxxx.so的程序。...
  • linux编译curl库的动态库so

    千次阅读 2014-11-11 22:33:23
    转载请注明出处:帘卷西风的专栏(http://blog.csdn.net/ljxfblog)  curl库是一个很强大的http开源库,... 在windows下还是很容易使用,如何使用的案例比比皆是,而且很容易就找到已经编译好的动态库进行测试,但是最后
  • 使用官方提供的config命令默认竟然没有生成 .so,解决办法执行 ./config 时增加参数 shared,例如: ./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl -Wl,-rpath,/usr/local/ssl/lib shared然后 ...
  • 编了一个动态库,写测试程序去调用动态库,程序编译通过,调用动态库里函数出错,通过加上动态库相关依赖库以及 extern“C”声明解决该错误   以下,详细说明解决经过: 首先,刚编译好的动态库需要配置好配置...
1 2 3 4 5 ... 20
收藏数 731,557
精华内容 292,622
关键字:

动态编译