public static void AddKnownType(string cppName, string csname, TypeInfo.PropertyType type)
 {
     if (AllJoynTypes.ContainsKey(cppName))
     {
         if (AllJoynTypes[cppName].Type != type)
         {
             throw new InvalidCastException();
         }
     }
     else
     {
         AllJoynTypes.Add(cppName, new TypeInfo()
         {
             CsName = csname, Type = type
         });
     }
 }
        private static string CppTypeToDotNetType(string type, bool isArray, bool isInput, bool isOutput)
        {
            string cstype    = null;
            string marshalAs = null;

            if (isOutput)
            {
                if (type == "char**")
                {
                    //type = "char*";
                }
                else if (type.EndsWith("*")) //We should only do this on value types I think
                {
                    type = type.Substring(0, type.Length - 1);
                    //Debugger.Break();
                }
            }
            switch (type)
            {
            case "void":
                return("void");

            case "char*":
                cstype    = "string";
                marshalAs = "UnmanagedType.LPStr";
                break;

            case "char**":
                if (isOutput)
                {
                    cstype    = "IntPtr[]";
                    marshalAs = "UnmanagedType.LPArray";
                }
                else
                {
                    cstype    = "string[]";
                    marshalAs = "UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr";
                }
                break;

            case "size_t":
                cstype = "UIntPtr"; break;

            case "size_t*":
                cstype = "UIntPtr[]"; break;

            case "bool":
                cstype = "bool"; break;

            case "uint16_t":
                cstype = "UInt16"; break;

            case "uint16_t*":
                cstype = "UInt16[]"; break;

            case "uint32_t":
                cstype = "UInt32"; break;

            case "uint32_t*":
                cstype = "UInt32[]"; break;

            case "uint64_t":
                cstype = "UInt64"; break;

            case "uint64_t*":
                cstype = "UInt64[]"; break;

            case "uint8_t":
                cstype = "byte"; break;

            case "uint8_t*":
                cstype = "byte[]"; break;

            //case "uint8_t**":
            //    cstype = "byte[][]"; break;
            case "char":
                cstype = "sbyte"; break;

            case "void*":
                cstype = "IntPtr"; break;

            case "int16_t":
                cstype = "Int16"; break;

            case "int16_t*":
                cstype = "Int16[]"; break;

            case "int32_t":
                //case "QCC_BOOL":
                //case "QStatus":
                cstype = "Int32"; break;

            case "int32_t*":
            case "QCC_BOOL*":
                cstype = "Int32[]"; break;

            case "int64_t":
                cstype = "Int64"; break;

            case "int64_t*":
                cstype = "Int64[]"; break;

            case "double":
                cstype = "double"; break;

            case "double*":
                cstype = "double[]"; break;

            default:
                break;
            }
            if (cstype == null)
            //if (type.StartsWith("alljoyn_"))
            {
                //if (type == "alljoyn_busattachment")
                //    Debugger.Break();
                string typename = type;
                //while(typename.EndsWith("*"))
                //    typename = typename.Substring(0, typename.Length - 1) + "[]";
                string baseTypeName = typename.Replace("[]", "").Replace("*", "");
                if (AllJoynTypes.ContainsKey(baseTypeName))
                {
                    var t = AllJoynTypes[baseTypeName];
                    if (t.Type == TypeInfo.PropertyType.StructType)
                    {
                    }
                    cstype = t.CsName;
                    //Convert C++ * array to C# array
                    if (!(isInput))
                    {
                        var arrayLength = typename.Where(tn => tn == '*').Count();
                        if (t.Type == TypeInfo.PropertyType.Pointer || t.Type == TypeInfo.PropertyType.StructType)
                        {
                            arrayLength--;
                        }
                        for (int i = 0; i < arrayLength; i++)
                        {
                            cstype += "[]";
                        }
                    }
                }
            }
            if (cstype == null && !UnknownTypes.ContainsKey(type))
            {
                System.Diagnostics.Debug.WriteLine(type);
                UnknownTypes.Add(type, null);
            }
            if (cstype == null)
            {
                cstype = "IntPtr";
            }

            if (isArray)
            {
                cstype += "[]";
            }
            StringBuilder sb = new StringBuilder();

            if (isOutput && isInput || marshalAs != null)
            {
                sb.Append("[");
                if (marshalAs != null)
                {
                    sb.Append($"MarshalAs({marshalAs})");
                }
                if (isInput && isOutput)
                {
                    if (sb.Length > 1)
                    {
                        sb.Append(", ");
                    }
                    sb.Append("In, Out");
                }
                if (type == "char**" && isOutput)
                {
                    isOutput = false;
                    if (sb.Length > 1)
                    {
                        sb.Append(", ");
                    }
                    sb.Append("Out");
                }
                sb.Append("]");
                if (isOutput && !isInput)
                {
                    sb.Append(" out ");
                }
            }
            sb.Append(cstype);
            return(sb.ToString());
        }