//==============================================================================
        /// <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);
    }