Методы C ++ / CLI XML в Dll для формы WPF - PullRequest
0 голосов
/ 12 июля 2011

Извините за длинный пост, вывод довольно большой.Недавно я начал тестировать C # и WPF, и я действительно наслаждаюсь творчеством и свободой, которую он предлагает для визуальных эффектов.Я начал преобразовывать функции приложения, над которым я сейчас работаю, в DLL, в основном, поэтому мне не нужно переделывать работу, которую я уже сделал, и потому что я хочу научиться и получить некоторый опыт в написании DLL и использовании взаимодействия.

Каждая функция до сих пор имела только один вход или выход.Однако мои последние две функции (которые берут список имен файлов и хэш самого файла и для каждого файла и хеш-код сохраняет его в файл xml) не работают так хорошо для меня.Я получаю вывод, но не в той форме, в которой я хочу, поэтому моя логика явно ошибочна, но я не уверен, как ее исправить.

Функции очень похожи, единственное отличие состоит в том, что создается новый xml, авторой обновляет существующий XML.Они оба прекрасно работали раньше как прямые функции C ++ / CLI, однако теперь, когда мне нужно использовать их в C #, я должен поместить их в итерации, чтобы они работали для каждого из файлов и их хэши отображались в списках.

Ниже приведена одна из функций в Dll, где я теперь заменил предыдущие жестко запрограммированные переменные, которые были бы listBox2-> Items [x] -> ToString (), как переменные, такие как CurrentFile, которые теперь определены в .cs.

public: void XMLUpdate(String^ Location, int NumberItems, String^ ProjectName, 
                String^ ProjectTC, String^ CurrentFile, String^ CurrentHash)
    {
        try
        {
            XmlDocument^ XmlDoc = gcnew XmlDocument();
            XmlDoc->Load(Location);

            XmlElement^ NewProject = XmlDoc->CreateElement("Project");
            NewProject->SetAttribute("Name", ProjectName);
            XmlDoc->DocumentElement->AppendChild(NewProject);

            XmlElement^ NewTestCycle =  XmlDoc->CreateElement("TestCycle");
            NewTestCycle->SetAttribute("Number", ProjectTC);
            NewProject->AppendChild(NewTestCycle);

            XmlElement^ NewFile = XmlDoc->CreateElement("Files");
            NewTestCycle->AppendChild(NewFile);

            for (int x = 0; x < NumberItems; ++x)
            {
                String^ FileName = CurrentFile;
                String^ Hash = CurrentHash;

                XmlElement^ NewFileName = XmlDoc->CreateElement("FileName");
                NewFileName->SetAttribute("File", FileName);
                NewFile->AppendChild(NewFileName);

                XmlElement^ NewHashCode = XmlDoc->CreateElement("HashCode");
                NewHashCode->SetAttribute("Code", Hash);
                NewFile->AppendChild(NewHashCode);
            }

            XmlDoc->Save(Location);
            return;
        }
        catch(Exception^)
        {
            return;
        }           
     }

Вот вызов метода из библиотеки dll в моей форме WPF:

        private void button2_Click(object sender, RoutedEventArgs e)
    {
        DllTest.Funtions Functions = new DllTest.Funtions();

        String Name = textBox1.Text;
        String TC = textBox2.Text;
        String Location = "C:\\Users\\brandonm\\Desktop\\Backup\\XML\\test1.xml";
        int Number = listBox2.Items.Count;

        for (int x = 0; x < listBox2.Items.Count; ++x)
        {
            Functions.XMLUpdate(Location, Number, TC, Name, listBox2.Items[x].ToString(),
                    listBox3.Items[x].ToString());
        }

    }

Вывод занимает только последний элемент в списке и дублирует его по номеру всписок в этом случае в списке было 3 имени файла, а во втором списке было 3 хеша. Вот пример:

<?xml version="1.0" encoding="utf-8"?>
<Project Name="New">
  <TestCycle Number="1">
  <Files>
    <FileName
      File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
    <HashCode
      Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
    <FileName
      File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
    <HashCode
      Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
    <FileName
      File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
    <HashCode
      Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
  </Files>
    </TestCycle>
  </Project>
</Project>

Итак, вот вторая функция, которая обновляет существующий XML и выдает мне совершенно другой вывод, но все женеверно, из вывода в новой функции.

public: void XMLNew(String^ Path, String^ ProjectName, String^ TCNumber, int NumberItems, 
                    array^ CurrentFile, array^ CurrentHashCode)
        {
            try
            {
                XmlWriterSettings^ settings = gcnew XmlWriterSettings();
                settings->NewLineOnAttributes = true;
                settings->Indent = true;
                settings->Encoding->UTF8;

                XmlWriter^ Writer = XmlTextWriter::Create(Path, settings);
                Writer->WriteStartDocument();

                Writer->WriteStartElement("Projects");

                Writer->WriteStartElement("Project");
                Writer->WriteAttributeString("Name", ProjectName);

                Writer->WriteStartElement("TestCycle");
                Writer->WriteAttributeString("Number", TCNumber);

                Writer->WriteStartElement("Files");

                for (int x = 0; x WriteStartElement("FileName");
                    Writer->WriteAttributeString("File", FileName);

                    //End the FileName element
                    Writer->WriteEndElement();

                    Writer->WriteStartElement("HashCode");
                    Writer->WriteAttributeString("Code", Hash);

                    //End the HashCode element
                    Writer->WriteEndElement();
                }

                //End Element for File
                Writer->WriteEndElement();

                //End Element for TestCycle
                Writer->WriteEndElement();

                //End element for Project
                Writer->WriteEndElement();

                //End element for Projects
                Writer->WriteEndElement();

                Writer->Flush();
                Writer->Close();
            }
            catch(Exception^)
            {
                return;
            }           
        }

Вызов метода:

private void button4_Click(object sender, RoutedEventArgs e)
    {
        DllTest.Funtions Functions = new DllTest.Funtions();

        String Name = textBox1.Text;
        String TC = textBox2.Text;
        String path = "C:\\Users\\brandonm\\Desktop\\Backup\\XML\\test1.xml";
        int Number = listBox2.Items.Count;

        for (int x = 0; x < listBox2.Items.Count; ++x)
        {
            Functions.XMLNew(path, Name, TC, Number, listBox2.Items[x].ToString(),
                listBox3.Items[x].ToString());
        }
    }

выход для этой, которая ближек тому, что мне нужно, поскольку он использует все элементы в списке, но дублирует их в каждом элементе. Мне нужен только один новый элемент с новыми файлами и их хэшами.

    <?xml version="1.0" encoding="utf-8"?>
    <Project Name="New">
    <TestCycle Number="1">
      <Files>
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
        <HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
        <HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
        <HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
      </Files>
    </TestCycle>
  </Project>
  <Project Name="2">
    <TestCycle Number="New">
      <Files>
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
        <HashCode Code="0E-C2-B1-A4-3C-D8-C0-51-96-0F-FF-19-BC-3A-CE-AC" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
        <HashCode Code="0E-C2-B1-A4-3C-D8-C0-51-96-0F-FF-19-BC-3A-CE-AC" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
        <HashCode Code="0E-C2-B1-A4-3C-D8-C0-51-96-0F-FF-19-BC-3A-CE-AC" />
      </Files>
    </TestCycle>
  </Project>
  <Project Name="2">
    <TestCycle Number="New">
      <Files>
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
        <HashCode Code="C0-7C-51-C2-92-70-1B-11-E0-26-6D-D5-B8-79-12-0D" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
        <HashCode Code="C0-7C-51-C2-92-70-1B-11-E0-26-6D-D5-B8-79-12-0D" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
        <HashCode Code="C0-7C-51-C2-92-70-1B-11-E0-26-6D-D5-B8-79-12-0D" />
      </Files>
    </TestCycle>
  </Project>
  <Project Name="2">
    <TestCycle Number="New">
      <Files>
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
        <HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
        <HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
        <HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
      </Files>
    </TestCycle>
  </Project>
    </Project>

Так что теперь вы можете видетьпроблема у меня есть циклы внутри циклов, вызывая вывод, который повторяет себя.Я могу опубликовать пример своего вывода, если вам нужно.

Но ради жизни я не могу обойти это, я пытался разделить функции на части, но я получаю ошибки, пытаясь это сделать.

Кто-нибудь может найти способ обойти это?Я только хочу полностью переписать методы в c #, если это моя единственная альтернатива, так как я хочу, чтобы все основные функции в dll.Пожалуйста, не ругайте меня за недостаток знаний, я все еще впервые изучаю и проверяю множество вещей.

Спасибо

1 Ответ

0 голосов
/ 13 июля 2011

Решил проблему:)

Я поместил элементы в списках в массив и затем вставил их таким образом.

Код, приведенный ниже, предназначен для одной функции, но они обаможно использовать те же идентичные изменения в структуре.

Метод DLL для создания нового XML, в DLL были изменены следующие строки: Завершено:

public: void XMLUpdate(String^ Location, int NumberItems, String^ ProjectName, 
                String^ ProjectTC, array<String^>^ CurrentFile, array<String^>^ CurrentHash)
    {
        try
        {
            XmlDocument^ XmlDoc = gcnew XmlDocument();
            XmlDoc->Load(Location);

            XmlElement^ NewProject = XmlDoc->CreateElement("Project");
            NewProject->SetAttribute("Name", ProjectName);
            XmlDoc->DocumentElement->AppendChild(NewProject);

            XmlElement^ NewTestCycle =  XmlDoc->CreateElement("TestCycle");
            NewTestCycle->SetAttribute("Number", ProjectTC);
            NewProject->AppendChild(NewTestCycle);

            XmlElement^ NewFile = XmlDoc->CreateElement("Files");
            NewTestCycle->AppendChild(NewFile);

            for (int x = 0; x < NumberItems; ++x)
            {
                String^ FileName = CurrentFile[x];
                String^ Hash = CurrentHash[x];

                XmlElement^ NewFileName = XmlDoc->CreateElement("FileName");
                NewFileName->SetAttribute("File", FileName);
                NewFile->AppendChild(NewFileName);

                XmlElement^ NewHashCode = XmlDoc->CreateElement("HashCode");
                NewHashCode->SetAttribute("Code", Hash);
                NewFile->AppendChild(NewHashCode);
            }

            XmlDoc->Save(Location);
            return;
        }
        catch(Exception^)
        {
            return;
        }           
     }

Что изменилось:

public: void XMLNew(String^ Path, String^ ProjectName, String^ TCNumber, int NumberItems, array<String^>^ CurrentFile, array<String^>^ CurrentHashCode)

и

for (int x = 0; x < NumberItems; ++x)
{
    String^ FileName = CurrentFile[x];
    String^ Hash = CurrentHashCode[x];

И затем вызывающая функция изменилась на это в C #:

private void button4_Click(object sender, RoutedEventArgs e)
{
    DllTest.Funtions Functions = new DllTest.Funtions();
    String Name = textBox1.Text;
            String TC = textBox2.Text;
            String path = "C:\\Users\\brandonm\\Desktop\\Backup\\XML\\test1.xml";
            int Number = listBox2.Items.Count;
            String[] Files = new String[Number];
            String[] Hashes = new String[Number];

            for (int i = 0; i < listBox2.Items.Count; i++)
            {
        object s = listBox2.Items[i];
                Files[i] = s.ToString();
            }

            for (int j = 0; j < listBox3.Items.Count; j++)
            {
                object s = listBox3.Items[j];
                Hashes[j] = s.ToString();
            }

            Functions.XMLNew(path, Name, TC, Number, Files, Hashes);
    }

И если бы я теперь сделал те же самые изменения и использовал ту же самую логику в другомтеперь они работают правильно

...