适用于自定义编译平台和编译符合,把C#源码文件编译成dll。(用于InjectFix之类的热更方案)

适用于unity2017环境,代码暂时不方便贴出记述一下思路。

参考:Unity官方C#源码 https://github.com/Unity-Technologies/UnityCsReference

1. 通过反射取用一些访问不到的Editor代码

  • GetCompilationDefines(EditorScriptCompilationOptions, BuildTargetGroup, BuildTarget)
  • GetUnityAssmblies(bool, BuildTargetGroup, BuildTarget)
  • GetPrecompiledAssemblies(bool, BuildTargetGroup, BuildTarget)
  • CompatibilityProfileToClassLibFolder(ApiCompatibilityLevel)

直接复制源码过来改动

  • struct PrecompiledAssembly
  • enum EditorScriptCompilationOptions
  • class MonoInstallationFinder

2. Unity编译dll的原理

  • 先生成一个编译参数的清单文件,包括编译符号定义、源代码文件、库引用等,可以在项目目录下的Temp/UnityTempFile-XXXXX查看。
  • 之后会通过类似mono.exe mcs.exe @Temp/UnityTempFile-XXX的命令来启动编译器进行编译

已经很明显了,要实现自定义编译dll,主要解决两个问题:

  • 怎么找到mono和mcs的路径
  • 怎么生成清单文件

3. 找到mono和mcs的路径

在MonoInstallationFinder.cs中直接增加函数

public static string GetMonoProfileLibDirectory(BuildTarget group)
{
ApiCompatibilityLevel compatibilityLevel = PlayerSettings.GetApiCompatibilityLevel(group);
string profile;
string monoInstall; // 因为生产环境配置比较固定, 写的比较糙
// 具体可查阅"mono"和"MonoBleedingEdge"文件夹的区别(旧版本|新版本)
if (compatibilityLevel == ApiCompatibilityLevel.NET_2_0)
{
profile = "2.0-api";
monoInstall = MonoBleedingEdgeInstallation;
}
else
{
profile = "unity"; // .net-2.0-subset
monoInstall = MonoInstallation;
}
}

4. 生成清单文件

unity2017对自定义dll名称有一定支持,但不是太好,还是使用默认的"Assembly-CSharp"这些,参考官方说明 https://docs.unity3d.com/2017.4/Documentation/Manual/ScriptCompileOrderFolders.html

写一个枚举方便使用


enum UnityDllNames
{
Assembly_CSharp_firstpass,
Assembly_CSharp,
Assembly_CSharp_Editor_firstpass,
Assembly_CSharp_Editor,
}

可以写出根据文件路径判断所属dll的函数UnityDllNames GetDllType(string path), 根据这四个dll的依赖关系,可以写出判断dll是否需要引用的参数bool NeedDllRef(UnityDllNames dll, UnityDllNames refDll),源代码文件很容易就可以列出来了

项目内的dll文件,结合路径和PluginImporter的值来判断是否引用;比较难处理的是Unity自己提供的引用

  • 通过最开始提到的GetUnityAssemblies()和GetPrecompiledAssemblies()可以获取部分,非编辑器构建下需要额外排除名字带有"Editor"的引用
  • 还有一些额外的固定引用,通过GetMonoProfileLibDirectory()获取路径拼接,System.Runtime.Serialization.dll,System.Xml.Linq.dll,UnityScript.dll,UnityScript.Lang.dll,Boo.Lang.dll
  • 可能还有一些遗漏或不一致的。如果不是直接在实际游戏中用到这个编译出来的dll,不需要做到和Unity生成的完全一致

通过GetCompilationDefines()获取编译符号定义

存在mcs.rsp的加一下

5. 执行编译

生成清单文件后,找到对应的mono、mcs路径,拼接执行即可,一般是MonoBleedingEdge/bin/mono.exe和MonoBleedingEdge/lib/mono/4.5/mcs.exe

unity2017自定义编译dll的更多相关文章

  1. 在SSIS中使用自定义的DLL文件

    原文:在SSIS中使用自定义的DLL文件 步骤1.开发dll(需要签名) using System;using System.Collections.Generic;using System.Text ...

  2. 自定义编译gdal库

    作者:朱金灿 来源:http://blog.csdn.net/clever101 使用下载下来的gdal库的makefile来编译gdal库,生成的gdal库的名字debug版本和release版本都 ...

  3. Delphi编译dll时出错"Cannot debug project unless a host application is defined.use the run|parameters...dialog box."

    问题: 在编写DLL程序的时候,按下F9或者按下那个绿色的箭头,会报错,如下 原因: 是因为你按下的F9或者那个绿色箭头是表示“Run”这个程序,但是DLL不是可执行文件,所以当然不能够运行,所以就会 ...

  4. Qmake 配置自定义编译过程

    Qmake 配置自定义编译过程 需求:动态更换资源文件 在 Windows10 下编写 Qt 项目时,有这样的需求: 程序用到的资源文件可以动态更换而不需要重新编译整个项目 解决方案 0.1 将所有的 ...

  5. windows下用GCC编译DLL

    此程序有3个文件,分别为 export.h .export.c .main.c export.h 文件内容 /*此头很有必要,别人在调用的时候知道有哪些方法*/ #ifdef BUILD_DLL #d ...

  6. MinGW g++.exe 编译 DLL 时,导出函数名带@的问题

    今天尝试用CodeBlocks写了一个简单的Dll,发现生成的 dll 文件导出的函数名后面都有一个 @xxx 从生成的 libDll2.def 中看到: EXPORTS DllMain@ @ Max ...

  7. 反编译DLL并修改DLL中的内容

    使用场景:针对当前用户因不愿意进行软件版本升级,但又希望可以解决当前问题,此时可以考虑通过反编辑DLL进行修改内容,然后重新生成新的DLL 操作步骤: 1.首先使用ILSpy.exe反编译DLL,查看 ...

  8. MinGW编译dll并引用

    记得某位神仙曾经说过:一个项目不使用dll简直是一场灾难.(滑稽) 这篇文章以A+B/A-B为范例,来介绍如何在MinGW下编译dll并引用. 首先你要安装MinGW,并配置好环境变量(不配置环境变量 ...

  9. Stupid && 祖传Fortran代码救赎之路(编译Dll)

    Stupid && 祖传Fortran代码救赎之路(编译Dll) gfortran编译动态库 在Windows平台下,Intel Fortran安装过于庞大且费事(现在集成到OneAP ...

  10. MinGW(GCC)编译DLL文件

    这两天用CB(Code::Blocks)写个小程序,要编译出DLL供VB(6)使用.CB使用mingw-gcc作为编译器,在库文件的产出上跟VC.VS之类的IDE略有不同. 由于C语言的基础知识不是太 ...

随机推荐

  1. Prometheus-3:一文详解promQL

    读前提示: 本文字数较多且紧凑,最好预留15min一次性看完,好营养,易吸收. promQL详解 Prometheus提供了内置的数据查询语言PromQL(全称为Prometheus Query La ...

  2. Net 编译器平台 --- Roslyn

    引言 最近做一个功能想要动态执行C#脚本,就是预先写好代码片段,在程序运行时去执行代码段,比如像这样(以下代码为伪代码): string scriptText = "int a = 1;in ...

  3. 即构SDK支持对焦、变焦、曝光调整,让直播细节清晰呈现

    对焦.变焦.曝光调整,摄影爱好者对这三个术语一定不陌生. 对焦是指通过相机对焦机构变动物距和相距的位置,使被拍物成像清晰的过程:变焦指的是在望远拍摄时放大远方物体,并使之清晰成像 :曝光调整是一种曝光 ...

  4. Unity自定义类使用携程--自身不继承MonoBehaviour

    [TOC] 参考: https://www.jianshu.com/p/67f498cb839b 话不多说,直接上代码 1 using System.Collections; 2 using Unit ...

  5. Spring—bean的作用域

    beans的作用域 单例模式(Spring默认模式) <?xml version="1.0" encoding="UTF-8"?> <bean ...

  6. 青少年CTF平台-Web-POST&GET

    题目描述 一星简单题,看我如何给你过了. 启动环境,等待三十秒先喝口水. 做题过程 访问题目地址,说让我们用GET方式提交一个名称为get且值为0的变量. 在URL后面加上?get=0,回车.已经成功 ...

  7. chrome浏览器插件react devtools、redux devtools,无需安装、解压即可用

    react devtools用于调试react代码,可以查看到props.state的值,以及定义的hooks,而redux devtools可以追踪到action的派发.store的变化,两个都是r ...

  8. [selenium]相对定位器

    前言 Relative Locators,相对定位器,是Selenium 4引入的一个新的定位器,相对定位器根据源点元素去定位相对位置的其它元素. 相对定位方法其实是基于JavaScript的 get ...

  9. 银河麒麟v10安装达梦数据库

    简介 达梦数据库是商业化的国产关系型数据库,体系架构比较像Oracle. 官方在线手册 原生安装 系统版本:银河麒麟V10服务器版 数据库版本:DM8 下载官方安装包,解压后有个ISO文件和包含sha ...

  10. Godot无法响应鼠标点击等输入事件时,检查这些内容

    注:本文以Godot 4.0 为基准,可能其他版本也能参考. 这是我用C#写项目时发现的,可能和gdscript使用者遇到的问题有一定区别. 如果你用Godot制作的游戏无法响应鼠标点击等输入事件,请 ...