1. 程式人生 > >Unity Windows&Mac 編譯和除錯外部C#動態庫(DLL)

Unity Windows&Mac 編譯和除錯外部C#動態庫(DLL)

目標實現

Windows 平臺

工具

  • Visual Studio 2015

  • Unity 5.6

  • Visual Studio 2015 Tools for Unity 

  • Python 2.7.9

步驟

  • 建立 C# 類庫工程

  • 引用UnityEngine.dll等其他庫

  • 新增【成功生成時】的【後期生成事件命令列】
    $(SolutionDir)Build/.Project$(ProjectName).py $(ConfigurationName) $(TargetDir) $(TargetName) $(ProjectDir)$(IntermediateOutputPath)

  • 編寫 Python 指令碼,以便編譯完畢,可以自動拷貝 DLL 等檔案到 Unity 工程

注意腳本里面要包含 pdb2mdb,例如:

if isWin:
    p = subprocess.Popen([currentPath + "/pdb2mdb", targetName + ".dll"], shell = True, cwd = targetPath)
    p.wait()

    shutil.copy(targetPath + targetName + ".dll.mdb", resPath + targetName + ".dll.mdb")

另外,需要用 precompile.exe來對 protobuf 的資料 dll 檔案進行序列化和反序列化,如下:

if isWin:
    p = subprocess.Popen([currentPath + "/precompile", targetName + ".dll", "-o:" + targetName + ".AOT.dll", "-t:AOTDataConfig" ], shell = True, cwd = targetPath)

除錯

在確定 DLL 對應的 mdb 檔案有拷貝到 Unity 工程,就可以直接通過【附加 Unity 除錯程式】來進行除錯

Mac 平臺

工具

  • Visual Studio for Mac 7.3.3

  • Unity 5.6

步驟

  • 將 Windows 平臺所建立工程拷貝到 Mac 下

  • 準備修改.csproj 檔案 和 Python 指令碼

因為安裝 Visual Studio for Mac 時已經附帶安裝了Mono.framework,所以不再需要額外安裝 mono,自帶的版本號為 5.4.1.7,如下所示:

編譯工程,發現生成了 DLL 和其對應的 pdb 檔案,使用命令:

/Library/Frameworks/Mono.framework/Versions/Current/bin/mono pdb2mdb.exe test.dll

提示不能進行轉換,如下所示:

Error: A portable PDB can't be converted to mdb.

Replacing mcs with csc in user scripts should be straightforward but small issues can arise as command line arguments accepted by csc and features are not identical to mcs. For example, csc generates Portable PDB (.pdb) debug files instead of Mono’s MDB (.mdb) format.

而Portable 版本的 pdb 檔案是無法轉換成 mdb 檔案,那麼就將編譯方式改成mcs.exe】,因為 Unity 也是用這種方式來編譯的,編輯器方法 EditorUtility.CompileCSharp呼叫如下:

更改每個 .csproj 工程配置檔案,在裡面新增如下屬性:

  <PropertyGroup Condition=" '$(OS)' == 'Unix' ">
    <CscToolExe>mcs.exe</CscToolExe>
  </PropertyGroup>

表示在非 Windows 平臺下使用【mcs.exe】進行編譯。再次編譯工程,可以發現在中間目錄 obj\Debug 目錄下生成了對應的 mdb 檔案,那麼修改 Python 指令碼,來將這個 mdb 檔案也拷貝到 Unity 工程下:

if isWin:
    p = subprocess.Popen([currentPath + "/pdb2mdb", targetName + ".dll"], shell = True, cwd = targetPath)
    p.wait()

    shutil.copy(targetPath + targetName + ".dll.mdb", resPath + targetName + ".dll.mdb")
else:
    shutil.copy(mdbPath + targetName + ".dll.mdb", resPath + targetName + ".dll.mdb")

另外,precompile.exe的呼叫也需要更改,如下:

if isWin:
    p = subprocess.Popen([currentPath + "/precompile", targetName + ".dll", "-o:" + targetName + ".AOT.dll", "-t:AOTDataConfig" ], shell = True, cwd = targetPath)
else:
    p = subprocess.Popen(["/Library/Frameworks/Mono.framework/Versions/Current/bin/mono", currentPath + "/precompile.exe", targetName + ".dll", "-o:" + targetName + ".AOT.dll", "-t:AOTDataConfig" ], shell = False, cwd = targetPath)

除錯

在確定 DLL 對應的 mdb 檔案有拷貝到 Unity 工程,就可以直接通過【Run】→【Attach to Process...】來進行除錯:

可以看到已經進行掛載除錯了。