**EDIT**: I ended up using Delegate.Create delegate and hook up my dll dynamically and not statically.
public void ConnectAssembly(string assemblyPath, string serializerTypeName)
{
if (!File.Exists(assemblyPath))
throw new IOException("Assembly path doesn't exist: " + assemblyPath);
var asm = Assembly.LoadFrom(assemblyPath);
var serializerType = asm.GetType(serializerTypeName);
if (serializerType == null)
throw new NullReferenceException("Serializer type was not found: " + serializerTypeName);
var serializeMethod = serializerType.GetMethod("Serialize", BindingFlags.Static | BindingFlags.Public);
var deserializeMethod = serializerType.GetMethod("Deserialize", BindingFlags.Static | BindingFlags.Public);
_serialize = (SerializationDelegate)Delegate.CreateDelegate(typeof(SerializationDelegate), null, serializeMethod);
_deserialize = (DeserializationDelegate)Delegate.CreateDelegate(typeof(DeserializationDelegate), null, deserializeMethod);
}
**EDIT**: Here's a video showing it in action:
https://www.youtube.com/watch?v=e-3a6qnVjmM&feature=youtu.be
In my firstpass dll, I have type `X` - I have a dynamically generated dll 'SerTest.dll' that I emit at in the firstpass, that references 'X'. So when Unity tries to compile firstpass, it tries to compile the dll 'SerTest' which references 'X' in firstpass, compilation fails.
-----Compiler Commandline Arguments:
Filename: "C:\Program Files\Unity\Editor\Data\Mono\bin\mono.exe"
Arguments: "C:\Program Files\Unity\Editor\Data\Mono\lib\mono\unity\smcs.exe" @Temp/UnityTempFile-71d970fa2565f064492790f199c48fd7
MONO_PATH: C:\Program Files\Unity\Editor\Data\Mono\lib\mono\unity
MONO_CFG_DIR: C:\Program Files\Unity\Editor\Data\Mono\etc
index: 68
Responsefile: Temp/UnityTempFile-71d970fa2565f064492790f199c48fd7 Contents:
-debug
-target:library
-nowarn:0169
-out:Temp/Assembly-CSharp-firstpass.dll
-r:"C:/Program Files/Unity/Editor/Data/Managed/UnityEngine.dll"
-r:"C:/Program Files/Unity/Editor/Data/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll"
-r:Assets/SerTest.dll <<<<<<<<<< !!!!!
-r:Assets/Dll/FastSerializer.dll
-r:"C:/Program Files/Unity/Editor/Data/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll"
-r:"C:/Program Files/Unity/Editor/Data/Managed/UnityEditor.dll"
-r:"C:\Program Files\Unity\Editor\Data\PlaybackEngines\iossupport\UnityEditor.iOS.Extensions.Xcode.dll"
-define:UNITY_5_0_0
-define:UNITY_5_0
-define:UNITY_5
-define:ENABLE_LICENSE_RENAME
-define:ENABLE_NEW_BUGREPORTER
-define:ENABLE_2D_PHYSICS
-define:ENABLE_4_6_FEATURES
-define:ENABLE_AUDIO
-define:ENABLE_CACHING
-define:ENABLE_CLOTH
-define:ENABLE_DUCK_TYPING
-define:ENABLE_FRAME_DEBUGGER
-define:ENABLE_GENERICS
-define:ENABLE_HOME_SCREEN
-define:ENABLE_IMAGEEFFECTS
-define:ENABLE_LIGHT_PROBES_LEGACY
-define:ENABLE_MICROPHONE
-define:ENABLE_MULTIPLE_DISPLAYS
-define:ENABLE_NEW_HIERARCHY
-define:ENABLE_PHYSICS
-define:ENABLE_PHYSICS_PHYSX3
-define:ENABLE_PLUGIN_INSPECTOR
-define:ENABLE_SHADOWS
-define:ENABLE_SINGLE_INSTANCE_BUILD_SETTING
-define:ENABLE_SPRITES
-define:ENABLE_TERRAIN
-define:ENABLE_UNITYEVENTS
-define:ENABLE_WEBCAM
-define:ENABLE_WWW
-define:ENABLE_AUDIOMIXER_SUSPEND
-define:ENABLE_NONPRO
-define:INCLUDE_DYNAMIC_GI
-define:INCLUDE_GI
-define:INCLUDE_IL2CPP
-define:PLATFORM_SUPPORTS_MONO
-define:RENDER_SOFTWARE_CURSOR
-define:UNITY_STANDALONE_WIN
-define:UNITY_STANDALONE
-define:ENABLE_SUBSTANCE
-define:ENABLE_TEXTUREID_MAP
-define:ENABLE_RUNTIME_GI
-define:ENABLE_MOVIES
-define:ENABLE_NETWORK
-define:ENABLE_MONO
-define:ENABLE_PROFILER
-define:UNITY_EDITOR
-define:UNITY_EDITOR_64
-define:UNITY_EDITOR_WIN
Assets/Plugins/DemoBehaviour.cs
-r:"C:\Program Files\Unity\Editor\Data\Mono\lib\mono\unity\System.Runtime.Serialization.dll"
-r:"C:\Program Files\Unity\Editor\Data\Mono\lib\mono\unity\System.Xml.Linq.dll"
-----CompilerOutput:-stdout--exitcode: 1--compilationhadfailure: True--outfile: Temp/Assembly-CSharp-firstpass.dll
Internal compiler error at Assets/Plugins/DemoBehaviour.cs(111,10):: exception caught while emitting MethodBuilder [DemoBehaviour::Demo]
The following assembly referenced from C:\Users\vexe\Desktop\FastSerializer\Assets\SerTest.dll could not be loaded:
Assembly: Assembly-CSharp-firstpass (assemblyref_index=1)
Version: 0.0.0.0
Public Key: (none)
The assembly was not found in the Global Assembly Cache, a path listed in the MONO_PATH environment variable, or in the location of the executing assembly (C:\Users\vexe\Desktop\FastSerializer\Assets\).
Could not load file or assembly 'Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
-----CompilerOutput:-stderr----------
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
File name: 'Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
To put it in a simplified way, here's what I have:
public class DemoBehaviour : MonoBehaviour
{
void Demo()
{
// access code in SerTest.dll
}
public class TestClass
{
// some fields....
}
}
That goes into the firstpass.
Then I emit a dll that references `TestClass` and does stuff with 'some fields'. The dll is called 'SerTest.dll' and is also located in the firstpass.
I really need to put that dll in the firstpass because I generate serialization code for user types, which could be in any pass, firstpass, plugins etc.
NOTE: I only get the errors when I try to do something with my generated Dll. So say there's a type called "SERIALIZER" in it, in the 'Demo' method, if I do `SERIALIZER.Serialize` (access the dll statically) I get those errors. I looked around and found [this answer][1] - apparently, if I reference the dll dynamically via reflection, it works! so instead of SERIALIZER.Serialize, I do typeof(SERIALIZER).GetMethod("Serialize").Invoke(....) which is really weird...
I really appreciate any help.
[1]: http://stackoverflow.com/questions/23924476/protobuf-net-and-unity3d-missing-assembly-reference-to-assembly-csharp-this-pro
↧