Unity跨程序DLL引用冲突及Android动态编译目录异常求助
解决方案:解决Unity Android动态编译路径问题与DLL重复引用冲突
一、修复Android上的DirectoryNotFoundException
在Android平台,Unity应用处于沙箱环境中,默认的系统临时目录(比如/tmp)可能没有读写权限,或者动态编译工具(CSharpCodeProvider/Roslyn)默认使用的路径不被允许。你需要手动指定Unity应用有权限访问的临时目录:
1. 针对CSharpCodeProvider的修改
创建TempFileCollection时,明确指定Unity的Application.persistentDataPath作为临时目录(这个目录是应用专属的可读写路径):
// 获取Unity可访问的临时目录 string tempDir = Application.persistentDataPath + "/TempCompile"; // 确保目录存在 Directory.CreateDirectory(tempDir); // 使用自定义临时目录创建TempFileCollection var tempFiles = new TempFileCollection(tempDir, false); // 初始化编译参数并指定临时文件集合 var provider = new CSharpCodeProvider(); var compileParams = new CompilerParameters { TempFiles = tempFiles, OutputAssembly = Path.Combine(tempDir, "DynamicAssembly.dll"), // 添加其他必要的引用和编译选项 };
2. 针对Roslyn的修改
使用Roslyn编译时,同样要将输出路径指定到Application.persistentDataPath下的可访问目录:
string outputDir = Application.persistentDataPath + "/DynamicAssemblies"; Directory.CreateDirectory(outputDir); var compilation = CSharpCompilation.Create( "DynamicAssembly", syntaxTrees: new[] { syntaxTree }, references: references, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithOutputDirectory(outputDir) ); // 编译到指定路径 var emitResult = compilation.Emit(Path.Combine(outputDir, "DynamicAssembly.dll"));
另外,记得在Unity项目的AndroidManifest.xml中添加外部存储读写权限,确保应用能正常访问persistentDataPath目录。
二、解决最初的DLL重复引用冲突问题
你遇到的函数重复冲突,本质是另一程序编译新DLL时,把Unity导出DLL中的类型实现也打包进了新DLL,导致Unity加载时出现重复类型。解决思路是让新DLL仅引用Unity导出DLL的元数据,不包含实现:
另一程序编译时仅引用Unity DLL,不嵌入代码
- 如果是命令行编译,确保仅通过
/reference参数添加对Unity导出DLL的引用,不要将Unity DLL的代码作为项目文件包含:csc /target:library /reference:UnityExported.dll /out:NewDynamic.dll YourNewClass.cs - 如果是用代码编译(比如另一程序也是.NET程序),则在
CompilerParameters中把Unity DLL的路径加入ReferencedAssemblies集合,不要将Unity DLL的代码加入编译源文件。
- 如果是命令行编译,确保仅通过
优化Unity端的DLL加载方式
加载新DLL时,优先使用Assembly.Load(byte[])加载DLL的字节流,而非Assembly.LoadFrom,这样可以避免路径依赖问题,同时确保直接复用Unity进程中已加载的原生类型。
额外注意事项
- Android平台上,动态生成的DLL必须放在Unity允许加载的路径下,
Application.persistentDataPath是最安全的选择,不要尝试访问系统级目录。 - 导出Unity DLL时,只包含你需要被外部调用的接口/类,不要包含Unity引擎核心类型(这些类型由Unity运行时本身提供,不需要导出),进一步降低冲突概率。
内容的提问来源于stack exchange,提问作者Tiernan Watson
相关产品推荐
相关产品推荐

