Использование внешних dll: различия между версиями
Dmitriy (обсуждение | вклад) |
Dmitriy (обсуждение | вклад) |
||
(не показаны 3 промежуточные версии этого же участника) | |||
Строка 1: | Строка 1: | ||
Создаем в Visual Studio библиотеку классов C#. Если собираемся передавать в длл указатели, то открываем свойства проекта, вкладка Построение и добавляем галочку Разрешить небезопасный код. | Создаем в Visual Studio библиотеку классов C#. Если собираемся передавать в длл указатели, то открываем свойства проекта, вкладка Построение и добавляем галочку Разрешить небезопасный код. | ||
Например, | Например, | ||
− | + | ||
− | < | + | <pre> using System; |
using System.Collections.Generic; | using System.Collections.Generic; | ||
using System.Linq; | using System.Linq; | ||
Строка 70: | Строка 70: | ||
} | } | ||
} | } | ||
− | ************* | + | </pre> |
− | < | + | В свойствах проекта выбираем вместо ANY x86, подключаем System.Security.Xml, System.Windows.Forms; |
− | + | ||
− | + | <p>Далее скачиваем архив с ExportDll,http://yadi.sk/d/N1hofxN-Fiz9i распаковываем. В файле Params.set должны быть указаны правильные пути для ilasm и ildasm. По умолчанию я выставил свои пути (Net Framework 4 и Visual Studio 2010). | |
+ | Далее или а )снова открываем свойств проекта, вкладка События построения. В поле Командная строка события после построения вписываем: | ||
+ | <pre>"c:\Program Files\ExportDll\ExportDll.exe" "$(TargetPath)"</pre> | ||
+ | где "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 прописываю прототипы функций либы | ||
+ | <pre> 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 | ||
+ | </pre> | ||
+ | 5. Пример вызова функций | ||
+ | <pre> 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) | ||
+ | </pre> |
Текущая версия на 15:47, 6 мая 2015
Создаем в 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)