Unity中将c#导出DLL动态库

18 篇文章 0 订阅
1 篇文章 0 订阅

本文只作为参考,个人水平有限,望见谅!
C#导出DLL,一开始就想到了将c++代码做成DLL的方法,各种复制粘贴宏定义,于是就找了一下C#导出DLL的一般方法,和后者如出一折,只是更简单一些,这里我就不详述了。于是乎就想到能不能写一个脚本,在Unity中可以直接导出动态库呢?再然后就知道了原来导出动态库全靠的是.net文件目录之下的csc.exe,这个程序的作用还不止导出.cs文件的dll,还可以编译甚至在控制台里写程序,这里也不详述了,有兴趣的话可以了解一下。
代码原理为开一个Thread将inspecor中已勾选的.cs文件、Library中的UnityEngine.dll等动态库以及用户自定义dll都复制到.net文件夹中,接着执行csc.exe,在输入流中写入对以上dll的引用、宏定义define、禁止out警告、导出*.cs文件为Library,最后再开一个Thread将生成的DLL文件拷贝至目标目录,并将之前复制进.net文件夹的文件全部删除。原本尝试在导出Dll之后 将scene中所有的.cs脚本引用替换成Dll中的引用,最终还是失败了,希望有高手指点!
下面是代码,DllExportInspector.cs主要用来自定义inspector,需要将此代码放入Asset/Editor文件夹中,DllExport.cs用来执行导出方法。

DllExportInspector.cs

using UnityEngine;
using System.Collections;
using UnityEditor;

[CustomEditor(typeof(DllExport))]
public class DllExportInspector:Editor
{
    bool init = false;
    public override void OnInspectorGUI()
    {



        DllExport d = (DllExport)target;

        GUILayout.Space(10);
        EditorGUILayout.LabelField("【代码文件】");
        foreach(var fn in d.fileList)
            fn.selected=EditorGUILayout.Toggle(fn.name,fn.selected);

        GUILayout.Space(10);
        EditorGUILayout.LabelField("【路径选择】");
        d.netPath = EditorGUILayout.TextField("csc文件路径:",d.netPath);
        d.savePath = EditorGUILayout.TextField("dll保存路径:", d.savePath);

        GUILayout.Space(10);
        EditorGUILayout.LabelField("【选项设置】");

        GUILayout.BeginHorizontal();
        d.delOrigional = EditorGUILayout.Toggle(d.delOrigional);
        EditorGUILayout.LabelField("是否删除原文件");
        EditorGUILayout.LabelField("                ");
        GUILayout.EndHorizontal();

        d.mainDLLName = EditorGUILayout.TextField("导出DLL文件名:", d.mainDLLName);

        d.defineString=EditorGUILayout.TextField("#define:", d.defineString);

        GUILayout.Space(20);
        GUILayout.BeginHorizontal();
        string btName = d.isConverting ? "Quit" : "Convert";

        if (GUILayout.Button(btName))
        {
            if (d.isConverting)
                d.Quit();
            else
                d.Convert();
        }
        if (GUILayout.Button("Reset"))
            d.Reset();
        GUILayout.EndHorizontal();

    }
}

DllExport.cs

using UnityEngine;
using UnityEditor;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Text;


[System.Serializable]
public class FileName
{
    public string fullName;
    public string directoryName;
    public string name;
    public bool selected;

   public FileName(string fName,string dName,string na)
    {
        fullName = fName;
        directoryName = dName;
        name = na;
        selected = true;
    }
}


public class DllExport : MonoBehaviour
{
    [MenuItem("Tools/DllExport")]
    static void AddScript()  {  Selection.activeGameObject.AddComponent<DllExport>(); }


    public string mainDLLName;
    public string netPath;
    public string savePath;
    public string defineString;

    public bool delOrigional;
    public bool isConverting;

    [SerializeField]
    public List<FileName> fileList = new List<FileName>();

    List<FileName> convertList = new List<FileName>();
    List<FileName> sysDllList = new List<FileName>();

    Thread exportThread;
    Thread opFileThread;

    public void Convert()
    {
        UnityEngine.Debug.Log("Convert...");
        sysDllList.Clear();
        convertList.Clear();

        foreach(var fn in fileList)
        {
            if (fn.selected)
                convertList.Add(fn);
        }
        string fPath;
        fPath = Application.dataPath;
        CopyFile(fPath, "*.cs", ref convertList,false);
        CopyFile(fPath, "*.dll", ref sysDllList,true);
        fPath = Application.dataPath.Substring(0, Application.dataPath.Length - 6) + "Library/UnityAssemblies";
        CopyFile(fPath, "*.dll", ref sysDllList,true);

        exportThread = new Thread(ExportFunction);
        exportThread.Start();
        isConverting = true;
    }
    public void Quit()
    {
        if (exportThread != null) exportThread.Abort();
        if (opFileThread != null) opFileThread.Abort();
        UnityEngine.Debug.Log("Quit!");
        isConverting = false;
    }
    public void Reset()
    {
        fileList.Clear();
        mainDLLName = "MainDLL";
        defineString = "EXAMPLE,EXAMPLE";
        netPath = @"C:\Windows\Microsoft.NET\Framework\v3.5";
        GetFiles(new DirectoryInfo(Application.dataPath), "*.cs", ref fileList);
        savePath = Application.dataPath.Substring(0, Application.dataPath.Length - 6).Replace("/", @"\") + @"DllExport\";
        delOrigional = isConverting=false;
    }

    void CopyFile(string path, string partern, ref List<FileName> fList,bool getfile)
    {
        if(getfile)
            GetFiles(new DirectoryInfo(path), partern, ref fList);
        foreach (var fStr in fList)
            File.Copy(fStr.fullName, netPath + @"\" + fStr.name, true);
    }
    void EndConvert()
    {
        foreach (var cn in convertList)
        {
            string trueName = cn.name.Substring(0, cn.name.Length - 3);
            string oPath = netPath + @"\" + trueName + ".dll";
            string sPath = savePath;
            if (!Directory.Exists(sPath))
                Directory.CreateDirectory(sPath);
            sPath += trueName + ".dll";
            if (File.Exists(oPath))
            {
                File.Copy(oPath, sPath, true);
                File.Delete(oPath);
            }
        }
        DeleteFile(ref fileList,delOrigional);
        DeleteFile(ref sysDllList,false);

    }
    void DeleteFile(ref List<FileName> fList,bool delOri)
    {
        foreach (var fn in fList)
        {
            if (delOri && File.Exists(fn.fullName))
                File.Delete(fn.fullName);
            string sPath = netPath + @"\" + fn.name;
            if (File.Exists(sPath))
                File.Delete(sPath);
        }
    }
    bool ExportSingleDll(string referDll, string target, string origion)
    {
        Process p = new Process();
        p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardInput = true;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.RedirectStandardError = true;
        p.StartInfo.CreateNoWindow = true;
        System.Console.InputEncoding = System.Text.Encoding.UTF8;
        p.Start();
        StreamWriter sw = p.StandardInput;
        p.StandardInput.WriteLine("");
        p.StandardInput.WriteLine("C:");
        p.StandardInput.WriteLine("cd "+netPath);
        p.StandardInput.WriteLine("csc" + referDll + GetDefineStr()+" /out:" + target + " /warn:0" + " /target:library " + origion); // GetReferStr(ref fList, " ")
        sw.Close();
        string logText = p.StandardOutput.ReadToEnd();
        if(logText.Contains("error"))
        {
            UnityEngine.Debug.LogError(logText);
            return false;
        }
        else
        {
            UnityEngine.Debug.Log(logText);
            return true;
        }
    }

    string GetReferStr(ref List<FileName> fList)
    {
        string str = "";
        foreach (var fn in fList)
            str += ToReferStr(fn.name);
        return str;
    }
    string ToReferStr(string str) { return " /r:" + str; }
    string GetDefineStr()
    {
        string str = "";
        string[] deStr = defineString.Split(',');
        foreach (var de in deStr)
            str += (" /define:" + de);
        return str;
    }
    void ExportFunction()
    {
        string mName = mainDLLName + ".dll";
       if( ExportSingleDll(GetReferStr(ref sysDllList), mName, " *.cs"))
        {
            System.Diagnostics.Process.Start("explorer.exe", savePath);
            UnityEngine.Debug.Log("Successful Convert!");
        }
        else
           UnityEngine.Debug.LogError("Fail Convert!");

        mName = mainDLLName + ".cs";
        convertList.Clear();
        convertList.Add(new FileName(mName, savePath, mName));
        opFileThread = new Thread(EndConvert);
        opFileThread.Start();

        isConverting = false;

    }
     void GetFiles(DirectoryInfo directory, string pattern, ref List<FileName> result)
     {
         if (directory.Exists || pattern.Trim() != string.Empty)
         {
             foreach (FileInfo info in directory.GetFiles(pattern))
             {
                 if(info.Name.Equals("DllExport.cs")) continue;
                 if (info.Name.Equals("DllExportInspector.cs")) continue;
                     result.Add(new FileName(info.FullName, info.DirectoryName, info.Name));
             }
             foreach (DirectoryInfo info in directory.GetDirectories())
                 GetFiles(info, pattern, ref result);
         }
     }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值