Использование внешних dll

Материал из Wiki МИАЦ ВО
Версия от 15:47, 6 мая 2015; Dmitriy (обсуждение | вклад)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к навигации Перейти к поиску

Создаем в Visual Studio библиотеку классов C#. Если собираемся передавать в длл указатели, то открываем свойства проекта, вкладка Построение и добавляем галочку Разрешить небезопасный код. Например,

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Xml;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ManagedCSharpDLL
{
    public static class UnmanagedExports
    {
        [System.Reflection.Obfuscation(Feature = "DllExport")]
        public static void TestINT(int val1)
        {
            System.Windows.Forms.MessageBox.Show(val1.ToString());
        }

        [System.Reflection.Obfuscation(Feature = "DllExport")]
        public static string Canonicalize(string document)
        {
            XmlDsigExcC14NTransform xmlTransform = new XmlDsigExcC14NTransform();
            xmlTransform.LoadInput(document);
            System.Windows.Forms.MessageBox.Show(document.ToString());
            string result = new StreamReader((MemoryStream)xmlTransform.GetOutput()).ReadToEnd();
            //C# метод канокализации не добавляет в XPath неймсппейс
/*            result = s.Replace("<XPath>", "<XPath xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\">");*/
            return result;
        }
        
        [System.Reflection.Obfuscation(Feature = "DllExport")]
        public static string Canonicalization(XmlNode node)
        {
            XmlDsigExcC14NTransform c14 = new XmlDsigExcC14NTransform();
            var nodeStream = new MemoryStream();
            XmlWriter writer = XmlWriter.Create(nodeStream);
            node.WriteTo(writer);
            writer.Flush();

            nodeStream.Position = 0;

            var transform = new XmlDsigExcC14NTransform();
            transform.LoadInput(node);
            var outputStream = (MemoryStream)transform.GetOutput(typeof(Stream));
            return new StreamReader(outputStream).ReadToEnd();

            //C# метод канокализации не добавляет в XPath неймсппейс
            // result = s.Replace("<XPath>", "<XPath xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\">");
            //todo: Поверить после! Тут они не попадаются, проверить нечем. 
        }
      [System.Reflection.Obfuscation(Feature = "DllExport")]
        public static void TestCallback(string passedString)
        {
            string displayValue = passedString;
            string returnValue = String.Empty;

            MessageBox.Show("C#: About to call the Callback. displayValue=" + displayValue + ", returnValue=" + returnValue);
            MessageBox.Show("C#: Back from the Callback. displayValue=" + displayValue + ", returnValue=" + returnValue);
        }

    }
}

В свойствах проекта выбираем вместо ANY x86, подключаем System.Security.Xml, System.Windows.Forms;

Далее скачиваем архив с ExportDll,http://yadi.sk/d/N1hofxN-Fiz9i распаковываем. В файле Params.set должны быть указаны правильные пути для ilasm и ildasm. По умолчанию я выставил свои пути (Net Framework 4 и Visual Studio 2010). Далее или а )снова открываем свойств проекта, вкладка События построения. В поле Командная строка события после построения вписываем:

"c:\Program Files\ExportDll\ExportDll.exe" "$(TargetPath)"

где "c:\Program Files\ExportDll\ExportDll.exe" путь к распакованной утилите. Нажимаем сохранить, далее строим решение, получаем в директории bin готовую DLL. или б) вручную выполняем ExportDll.exe *.dll , получаем готовую DLL.

Полученный результат нужно проверить. В этом поможет утилита Dependency Walker http://www.dependencywalker.com/ Запускаем, кидаем в нее полученную длл и смотрим, чтобы появились справа посредине функции

http://jonxxx.me/13-metatrader/15-eksport-funktsij-iz-net-dll-c-dllexport-net-framework-v-metatrader

Далее нужно выкачать модифицированный libMaker http://www.clarionaddins.com/_downloads/LibMaker.zip, т.к. стандартный может работать только с короткими именами и добавляет '/' в названия функций в lib. Запускаем libmaker, импортируем dll, удаляем что не надо, экспортируем в *.lib. Получаем готовые 2 файла *.lib и *.dll

Далее эти файлы нужно подцепить в Clarion. 1. Копируем файлы в директорию с программой. (Файлы .DLL размещаю в папку \Bin,.LIB - в папку \Lib,.INC - в папке \Libsrc) 2. Файл полученной библиотеки подключается в проекте (Solution->Library, objects and resource files) 3. В глобальных Embeds в ветке Inside the Global Map пишется include('csharp.inc') 4. В файле csharp.inc прописываю прототипы функций либы

    Module('TestDLL.dll')
Canonicalization    PROCEDURE(*CString node),NAME('Canonicalization'),PASCAL,RAW,DLL(TRUE)
TestINT        	    PROCEDURE(long val1),NAME('TestINT'),PASCAL,RAW,DLL(TRUE)
TestCallback        PROCEDURE(*CString passedString),NAME('TestCallback'),PASCAL,RAW,DLL(TRUE)
Canonicalize        PROCEDURE(*CString document),NAME('Canonicalize'),PASCAL,RAW,DLL(TRUE)
    END

5. Пример вызова функций

          a = 'Call Test Worked'
        Message('Clarion: Send message: ' & a)
          val1=4444
          TestINT(val1)
        TestCallback(a)
          a='<test>dasklhasdfkl</test>'
      !    Canonicalization(a)
          Canonicalize(a)
          message(a)