Avatar billede farving Nybegynder
05. december 2007 - 14:45 Der er 4 kommentarer og
1 løsning

cannot convert from System::Array to cli::array<Type>

Hej

Jeg sidder og er ved at lave et projekt...

Jeg har fået lavet en dll fil i C# da jeg synes det var nemmere at skrive end i C++, dog bruger jeg VC++ til at lave mit UI...

Mit problem er at jeg i C++ ikke kan få lavet et globalt array af typen System::Array, så er det muligt i C# at lave et array af typen cli::array<Type>??

Hvis ikke, hvordan får jeg så drejet mit C++ til at lave et globalt array af typen System::Array...

mit array nu er:
array<System::Array^> ^ schedules; (C++)
og det prøver jeg at fylde med et array sendt fra min C# funktion som returnerer:
Array schedules = new Array[7];

Håber nogen kan hjælpe mig og forstå mit problem...

Mvh Carsten
Avatar billede arne_v Ekspert
06. december 2007 - 04:15 #1
Det burde da være muligt at sende et array fra C++ CLI til C#.

Nu giver du jo ikke meget kode, men et lille demo eksempel:

#using <mscorlib.dll>

using namespace System;

#using <Demo.dll>

int main()
{
    array<int>^ ia = gcnew array<int>(10);
    for(int i = 0; i < ia->Length; i++) ia[i] = i + 1;
    Demo^ d = gcnew Demo();
    array<int>^ res = d->Fun(ia);
    for(int i = 0; i < res->Length; i++) Console::WriteLine(res[i]);
    return 0;
}


using System;

public class Demo
{
    public int[] Fun(int[] ia)
    {
        int[] res = new int[ia.Length];
        for(int i = 0; i < res.Length; i++) res[i] = ia[i] + 1;
        return res;
    }
}
Avatar billede farving Nybegynder
06. december 2007 - 08:51 #2
Det er nu den anden vej det skal gå, det er et CLI array der skal fyldes med data returneret fra et almindeligt array i C# (hvilket according to VC express er System::Array)...

Men min dll-fil (hvor det er readAttribute der retunerer arrayet:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;

namespace functions
{
    public class handleXML
    {
        private string path;
        private FileStream fs;
        // Instance constructor
        public handleXML(string path)
        {
            this.path = path;
        }
        // copy constructor
        public handleXML(handleXML prevXML)
        {
            path = prevXML.path;
        }
        public Array readAttribute(int attr)
        {
            fs = new FileStream(path, FileMode.Open);
            XmlReader r = XmlReader.Create(fs);
            Array schedules = new Array[7];
            int i = 0;
                while (r.Read())
                {
                    schedules.SetValue(r.GetAttribute(attr), i);
                    i++;

                }
            fs.Close();
            return schedules;
        }
        public Int32 updateAttribute(int attr, String value)
        {
            fs = new FileStream("schedule.xml", FileMode.Create);
            XmlReader r = XmlReader.Create(fs);
            XmlWriter w = XmlWriter.Create(fs);
            w.WriteStartDocument();
            w.WriteStartElement("days");
            while (r.Read())
            {
                if (r.NodeType == XmlNodeType.Element)
                {
                    w.WriteStartElement(r.Name);
                    if (r.HasAttributes)
                    {
                        for (int i = 0; i < r.AttributeCount; i++)
                        {
                            if (i == attr && r.GetAttribute(i) == value)
                            {
                                if (attr == 0)
                                {
                                    w.WriteAttributeString("timeOfAlarm", value);
                                }
                                else
                                {
                                    w.WriteAttributeString("pathToSound", value);
                                }
                            }
                        }
                    }
                    w.WriteEndElement();
                }
            }
            w.WriteEndElement();
            w.Flush();
            fs.Close();
            return 0;
        }
       
    }
}

I mit VC++ er det den her stump kode der opretter objektet, laver kaldet og tilskriver værdien (sidste linie der fejler):
XMLpath = "schedule.xml";
handleXML xml = gcnew handleXML(XMLpath);
schedules = xml.readAttribute(0);

schedules er et array oprettet globalt vha:
private: array<System::Array^> ^ schedules;

Men kan være det er min opsætning af funktionen der giver anledning til problemet?

Mvh Carsten
Avatar billede farving Nybegynder
06. december 2007 - 10:37 #3
Kan være det lige skal siges at det er strings der skal fyldes i arrayet... Og har lige prøvet at sende arrayet med og det giver stadig samme fejl... Som om det bliver converteret i C# men kan ikke converteres tilbage...

Mvh carsten
Avatar billede farving Nybegynder
06. december 2007 - 10:57 #4
Okay jeg fik løst fejlen... Jeg fik valgt den rigtige datatype så det ser ud som følge:
C++:
globale array:
private: array<String^> ^ schedules;
local array:
handleXML xml = gcnew handleXML(XMLpath);
array<String^> ^ tmpSchedules = gcnew array<String^>(7);
schedules = xml.readAttribute(tmpSchedules);
C# funktionen:
        public String[] readAttribute(String[] arr)
        {
            fs = new FileStream(path, FileMode.Open);
            XmlReader r = XmlReader.Create(fs);
            int i = 0;
                while (r.Read())
                {
                    arr[i] = r.GetAttribute(0);
                    i++;

                }
            fs.Close();
            return arr;
        }
Så smid et svar, dit eksempel ledte mig ind på det :)
Avatar billede arne_v Ekspert
25. februar 2008 - 04:11 #5
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester