//======================================================================= /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> //======================================================================= protected override void Dispose(bool disposing) { if (!disposed) { try { if ((disposing && miDelInstance != null) && (modelObj != null)) { Object[] argArray = null; miDelInstance.Invoke(modelObj, argArray); } if (disposing && !FDllHandle.Equals(IntPtr.Zero)) { TOSInterface.LibUnload(FDllHandle); FDllHandle = IntPtr.Zero; } disposed = true; } finally { base.Dispose(disposing); } } }
//======================================================================= /// <summary> /// Initialise all the properties in the propertyList from the component description. /// </summary> //======================================================================= protected Boolean InitFromComponentDescription() { Boolean readProperties = false; //find the full path to the dll for the component String ComponentType = Controller.ApsimData.Find(NodePath).Type; List <String> DllFileNames = Types.Instance.Dlls(ComponentType); FDllFileName = DllFileNames[0]; FDllFileName = Configuration.RemoveMacros(FDllFileName); if ((propertyList.Count == 0) && File.Exists(FDllFileName)) //if no properties yet { String descr = ""; TOSInterface.CPUArchitecture arch; TOSInterface.CompilationMode mode = TOSInterface.isManaged(FDllFileName, out arch); //now I can probe this dll for it's description. CPI mixed mode wrapper/comp has a native interface if ((mode == TOSInterface.CompilationMode.Native) || (mode == TOSInterface.CompilationMode.Mixed)) { descr = getNativeDescription(FDllFileName); } else if (mode == TOSInterface.CompilationMode.CLR) { descr = getDotNetDescription(FDllFileName); } if (descr.Length > 0) { TComponentDescrParser comp = new TComponentDescrParser(descr); //need to read all the properties information String propertySDML = comp.firstProperty(); propertyList.Clear(); while (propertySDML.Length > 0) { //create a property attribute of this class defineNewProperty(propertySDML); propertySDML = comp.nextProperty(); } readProperties = true; } } return(readProperties); }
//============================================================================== /// <summary> /// Initialise this component using the dialog inbuilt into the component dll. /// </summary> /// <param name="simulation">unused</param> /// <returns>True if successful</returns> //============================================================================== public bool Initialise(String filename, ref String sInitSDML) { Int32 len = 0; bool result = false; IntPtr sim = IntPtr.Zero; FDllHandle = TOSInterface.loadDll(filename); if (!FDllHandle.Equals(IntPtr.Zero)) { IntPtr procAddr = TOSInterface.LibGetAddr(FDllHandle, "editComponentSDML"); if (!procAddr.Equals(IntPtr.Zero)) { try { fpEditComponentSDML = (PEditCompSDML)Marshal.GetDelegateForFunctionPointer(procAddr, typeof(PEditCompSDML)); result = fpEditComponentSDML(sInitSDML, IntPtr.Zero, ref len, sim); } catch (Exception) { MessageBox.Show("Could not open editor.", "Error"); } } else { MessageBox.Show("No editor found.", "Information"); } if (result) { StringBuilder sSDML = new StringBuilder(len); IntPtr procAddr_Get = TOSInterface.LibGetAddr(FDllHandle, "getEditedSDML"); if (!procAddr_Get.Equals(IntPtr.Zero)) { fpGetEditedSDML = (PGetEditedSDML)Marshal.GetDelegateForFunctionPointer(procAddr_Get, typeof(PGetEditedSDML)); fpGetEditedSDML(sSDML); } sInitSDML = sSDML.ToString(); } } return(result); }
//======================================================================= /// <summary> /// Accesses the component dll to get the component description SDML text. /// </summary> /// <param name="filename">The full path name of the component dll.</param> /// <returns>The component description xml.</returns> //======================================================================= public String getNativeDescription(String filename) { FDllHandle = TOSInterface.loadDll(filename); if (!FDllHandle.Equals(IntPtr.Zero)) { IntPtr procAddr = TOSInterface.LibGetAddr(FDllHandle, "getDescriptionLength"); if (!procAddr.Equals(IntPtr.Zero)) { Int32 lLength = 0; fpGetDescrLength = (PGetDescriptionLength)Marshal.GetDelegateForFunctionPointer(procAddr, typeof(PGetDescriptionLength)); fpGetDescrLength("", ref lLength); //now get the description. Native components construct an instance during getDescription() procAddr = TOSInterface.LibGetAddr(FDllHandle, "getDescription"); if (!procAddr.Equals(IntPtr.Zero)) { StringBuilder sb = new StringBuilder(lLength); fpGetDescr = (PGetDescription)Marshal.GetDelegateForFunctionPointer(procAddr, typeof(PGetDescription)); fpGetDescr("", sb); FCompDescription = sb.ToString(); } } } return(FCompDescription); }
//========================================================================= /// <summary> /// Return the XML from a DLL probe /// </summary> static public string ProbeDLLForDescriptionXML(string TypeName, string DllFileName) { String descr = ""; DllFileName = Configuration.RemoveMacros(DllFileName); if (File.Exists(DllFileName)) { string ModuleName = Path.GetFileNameWithoutExtension(DllFileName); string ModelConfiguration = Types.Instance.ModelContents(TypeName); if (ModelConfiguration == "") { ModelConfiguration = Types.Instance.ModelContents(TypeName, ModuleName); } if (ModuleName == "SoilWater" || ModuleName == "SoilNitrogen") { ModelConfiguration = "<" + ModuleName + ">" + ModelConfiguration + "</" + ModuleName + ">"; } string className = ModuleName; if (string.Compare(className, TypeName, true) != 0) { className = className + '.' + TypeName; } // Write some .sim script to pass to the DLL. string initScript = "<component name=\"" + ModuleName + "\" executable=\"" + DllFileName + "\" class =\"" + className + "\">\r\n"; initScript += " <initdata>\r\n"; initScript += ModelConfiguration + "\r\n"; initScript += " </initdata>\r\n"; initScript += "</component>"; Utility.CompilationMode typeOfAssembly = Utility.isManaged(DllFileName); if (typeOfAssembly == Utility.CompilationMode.CLR) { // Is this a CPI type fully-managed assembly? Assembly modelAssembly = Assembly.LoadFrom(DllFileName); Type[] assemblyTypes = modelAssembly.GetTypes(); Type modelType = null; foreach (Type typeInfo in assemblyTypes) { if (typeInfo.FullName == "CMPComp.TGCComponent") { modelType = typeInfo; break; } } if (modelType != null) { MethodInfo miGetDescription = modelType.GetMethod("description"); if (miGetDescription != null) { try { Object[] argArray = new Object[3]; argArray[0] = (uint)0; argArray[1] = (uint)0; argArray[2] = (uint)0; //argArray[2] = (MessageFromLogic)null; //call the constructor Object modelObj = Activator.CreateInstance(modelType, argArray); if (modelObj != null) { Object[] args = new Object[1]; args[0] = initScript; descr = (String)miGetDescription.Invoke(modelObj, args); } } catch (MissingMethodException e) { Console.WriteLine(e.Message); } } } else { // IF this is a mixed-mode .net component then redirect request to the wrapper DLL. DllFileName = Path.Combine(Configuration.ApsimBinDirectory(), "DotNetComponentInterface.dll"); typeOfAssembly = Utility.isManaged(DllFileName); } if (!File.Exists(DllFileName)) { throw new Exception("Cannot find DLL: " + DllFileName); } } if (typeOfAssembly == Utility.CompilationMode.Native || typeOfAssembly == Utility.CompilationMode.Mixed) { //access the native component PGetDescriptionLength fpGetDescrLength; PGetDescription fpGetDescr; IntPtr dllHandle = TOSInterface.loadDll(DllFileName); if (dllHandle.Equals(IntPtr.Zero)) { throw new Exception("Failed to load dll " + DllFileName + "\n"); } IntPtr procAddr = TOSInterface.LibGetAddr(dllHandle, "getDescriptionLength"); if (!procAddr.Equals(IntPtr.Zero)) { Int32 lLength = 0; fpGetDescrLength = (PGetDescriptionLength)Marshal.GetDelegateForFunctionPointer(procAddr, typeof(PGetDescriptionLength)); fpGetDescrLength(initScript, ref lLength); //now get the description. Native components construct an instance during getDescription() procAddr = TOSInterface.LibGetAddr(dllHandle, "getDescription"); if (!procAddr.Equals(IntPtr.Zero)) { StringBuilder sb = new StringBuilder(lLength); fpGetDescr = (PGetDescription)Marshal.GetDelegateForFunctionPointer(procAddr, typeof(PGetDescription)); fpGetDescr(initScript, sb); descr = sb.ToString(); } } } } return(descr); }