none
Как правильно создавать dll и подключать их к приложению Windows Forms? RRS feed

  • Вопрос

  • Сначала как обычно создаю библиотеку с функциями, обозначенными extern "C" _declspec(dllexport) ?

    Затем включаю .h-файл библиотеки в проект Windows Forms.

    Что затем? Установить свойство Linker->Additionals Dependencies, выбрав там свой lib-файл? Где он должен находиться, в какой папке? Где должна находиться моя dll? (Хотелось бы рядом с exe, как это сделать?)

    Какие-то из этих шагов неправильные?

    9 марта 2012 г. 11:11

Ответы

  • Обычные dll (Неуправляемые, написанные на C или C++) напрямую подключить к приложению написанному для .Net Framework не получится. Использовать код неуправляемой библиотеки можно только при помощи маршалинга. А управляемую dll Вы можете создать как библиотеку классов.Важно понять что управляемые и неуправляемые dll это совершенно разные и несовместимые вещи на двоичном уровне, одинаковы у них только расширение в назании и всё, на этом сходства заканчиваются. Есди Вам нужно создать новую библиотеку классов для WinForms просто создаёте новую библиотеку классов(File->New -> Projekt ->Class Library). А если использовать функциональность неуправляемого кода, то нужно применить библиотеку маршалинга.

    • Предложено в качестве ответа Abolmasov Dmitry 12 марта 2012 г. 8:49
    • Помечено в качестве ответа donaire 12 марта 2012 г. 9:19
    9 марта 2012 г. 13:40
    Модератор
  • > как сделать подключение через маршаллинг? А системные библиотеки user, kernel и т.д. каким образом подключаются?
      
     
    из неуправляемых dll можно использовать функции, подключив их с помощью DllImportAttribute и extern 
    примерно так: 

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

     


    • Изменено Malobukv 10 марта 2012 г. 8:50
    • Предложено в качестве ответа Malobukv 12 марта 2012 г. 5:42
    • Помечено в качестве ответа donaire 12 марта 2012 г. 9:20
    10 марта 2012 г. 8:49
  • > Мне просто нужна библиотека без всяких классов, пусть управляемая, просто несколько функций. Я создаю ClassLibrary, ок. [...] Затем второй разработчик должен взять мою библиотеку и как-то подключить её к своему проекту Windows Forms. 
     
     
    в Visual Studio создайте проект типа Class Library. в нем определите функции. 
    если код на C#, то примерно так:
      

    namespace Some
    {
        public static class Test
        {
            public static void Run()
            {
            }
        }
    }


    после компиляции получится .dll-файл, который можно подключить к WinForms проекту.
    (см. выше по теме). в WinForms для вызова Run надо указать Some.Test.Run();
     
     

    • Помечено в качестве ответа donaire 13 марта 2012 г. 8:30
    12 марта 2012 г. 10:17
  • "То есть таким способом можно создать библиотеку классов, а создать библиотеку с функциями без классов, да ещё чтобы подключать к проекту заголовочный файл, не получается. Файл exe не видит в библиотеке функции, только классы. А через заголовочный файл вообще непонятно как работать." - в .Net каждый метод(функция) должен принадлежать определённому классу. Т.е. сами по себе методы, как в C/С++, существовать не могут, они должны быть определены в каком либо типе(классе).

    • Помечено в качестве ответа donaire 13 марта 2012 г. 8:30
    12 марта 2012 г. 20:04
    Модератор
  • Для общения форм внутри одного приложения в WinForms не требуется использовать SendMessage. В .NET есть свой механизм - события, делегаты. Вот статья об этом на rsdn - Делегаты и события


    Для связи [mail]

    • Помечено в качестве ответа donaire 13 марта 2012 г. 13:12
    13 марта 2012 г. 8:46

Все ответы

  • Обычные dll (Неуправляемые, написанные на C или C++) напрямую подключить к приложению написанному для .Net Framework не получится. Использовать код неуправляемой библиотеки можно только при помощи маршалинга. А управляемую dll Вы можете создать как библиотеку классов.Важно понять что управляемые и неуправляемые dll это совершенно разные и несовместимые вещи на двоичном уровне, одинаковы у них только расширение в назании и всё, на этом сходства заканчиваются. Есди Вам нужно создать новую библиотеку классов для WinForms просто создаёте новую библиотеку классов(File->New -> Projekt ->Class Library). А если использовать функциональность неуправляемого кода, то нужно применить библиотеку маршалинга.

    • Предложено в качестве ответа Abolmasov Dmitry 12 марта 2012 г. 8:49
    • Помечено в качестве ответа donaire 12 марта 2012 г. 9:19
    9 марта 2012 г. 13:40
    Модератор
  • А есть примеры как сделать подключение через маршаллинг?

    А системные библиотеки user, kernel и т.д. каким образом подключаются? Где для них маршаллинг прописан?

    9 марта 2012 г. 23:13
  • А на чём написана Ваша библиотека? И зачем использовать системные dll указанные Вами?
    10 марта 2012 г. 6:10
    Модератор
  • > как сделать подключение через маршаллинг? А системные библиотеки user, kernel и т.д. каким образом подключаются?
      
     
    из неуправляемых dll можно использовать функции, подключив их с помощью DllImportAttribute и extern 
    примерно так: 

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

     


    • Изменено Malobukv 10 марта 2012 г. 8:50
    • Предложено в качестве ответа Malobukv 12 марта 2012 г. 5:42
    • Помечено в качестве ответа donaire 12 марта 2012 г. 9:20
    10 марта 2012 г. 8:49
  • Мне просто нужно создать библиотеку с функциями и подключить её к приложению Windows Form. Библиотеку без классов. только функции.

    А системные dll (там они в линкер все вместе добавляются) нужны, например, чтобы отправить сообщение окну SendMessage(hWnd, WM_USER+2, ... и т.д.

    10 марта 2012 г. 11:43
  • > Мне просто нужно создать библиотеку с функциями и подключить её к приложению Windows Form.
     
     
    в Visual Studio создайте проект Windows Forms Application;
    после этого добавьте новый проект: File - Add - New Project... - Class Library;
    в Solution Explorer будут два проекта: WindowsFormsApplication1 и ClassLibrary1;
    надо выделить проект WindowsFormsApplication1 и в контекстном меню выбрать: Add Reference... - ClassLibrary1

      
      

    • Предложено в качестве ответа Malobukv 12 марта 2012 г. 5:42
    10 марта 2012 г. 12:28
  • Если с нуля, то лучше управляемую. А почему не хотите использовать классы?
    10 марта 2012 г. 13:46
    Модератор
  • Уважаемый пользователь,

    Если ответ решит вашу проблему, то, пожалуйста, не забудьте ответить его. Для этого под каждым сообщением есть кнопка 'Пометить как ответ'.

    Посмотрите еще раз ответы Yatajga, они раскрывают суть вопроса. И также ответы Malobukv, в них приведены примеры.

    Спасибо.


    Для связи [mail]

    12 марта 2012 г. 8:53
  • Да, когда я заканчиваю задавать вопросы по теме, я всегда отмечаю как ответ, в том числе и Вас-). Как только разберусь с этой темой, обязательно помечу.
    12 марта 2012 г. 9:01
  • Мне просто нужна библиотека без всяких классов, пусть управляемая, просто несколько функций. Я создаю ClassLibrary, ок. Туда можно написать функции (наверное, можно ли???) и классы (один с именем Class1 там уже есть). Я создаю эту библиотеку отдельно, а затем мне нужно передать её уже в виде готового файла .dll и файла заголовков .h другому разработчику. Всё. Мне не нужно объединять их в одном проекте.

    Затем второй разработчик должен взять мою библиотеку и как-то подключить её к своему проекту Windows Forms. Где какие ссылки добавлять? На что ссылки? lib-файлы создаются в первом проекте, если поставить перед функцией (хотя бы одной) расширение extern "C" _declspec(dllexport).

    Как подключать системную dll понятно: нужно включить #include <windows.h>, затем в настройках Project->MyProject properties выбрать Linker->Input->Additionals Dependences, щёлкнуть на кнопке и поставить галочку рядом со списком .lib файлов user32, gdi32, kernel32 и т.д. Тут всё понятно. Как аналогичным образом подключить свою библиотеку?

    У неё должен быть свой .lib файл? Как его создать при создании библиотеки, если нельзя (нельзя?) использовать extern "C" _declspec(dllexport)? Где он должен находится? Если сама библиотека находится в той же папке, что и .exe файл, где прописать путь к ней?

    12 марта 2012 г. 9:39
  • > Мне просто нужна библиотека без всяких классов, пусть управляемая, просто несколько функций. Я создаю ClassLibrary, ок. [...] Затем второй разработчик должен взять мою библиотеку и как-то подключить её к своему проекту Windows Forms. 
     
     
    в Visual Studio создайте проект типа Class Library. в нем определите функции. 
    если код на C#, то примерно так:
      

    namespace Some
    {
        public static class Test
        {
            public static void Run()
            {
            }
        }
    }


    после компиляции получится .dll-файл, который можно подключить к WinForms проекту.
    (см. выше по теме). в WinForms для вызова Run надо указать Some.Test.Run();
     
     

    • Помечено в качестве ответа donaire 13 марта 2012 г. 8:30
    12 марта 2012 г. 10:17
  • Создаю библиотеку, код на С++ примерно такой же. Для примера создал класс с функцией в нём и просто функцию. Компилирую, всё нормально.

    Теперь копирую созданную dll в папку с проектом exe, щёлкаю правой кнопкой на имени проекта, выбираю References->Add New Reference, там выбираю свою dll, она появляется в списке рядом с System, System.Drawing и т.д.

    Далее просто вызов в коде DllNamespace::MyFunction(); либо DllNamespace::MyClass::MyClFunction(); - для cлучая с классом всё работает.

    Если же без класса просто функцию, выдаёт простую ошибку: MyFunction identifier not found. Если включить .h файл, то уже выдаст unresolved externals.

    То есть таким способом можно создать библиотеку классов, а создать библиотеку с функциями без классов, да ещё чтобы подключать к проекту заголовочный файл, не получается. Файл exe не видит в библиотеке функции, только классы. А через заголовочный файл вообще непонятно как работать.
    12 марта 2012 г. 11:29
  • "То есть таким способом можно создать библиотеку классов, а создать библиотеку с функциями без классов, да ещё чтобы подключать к проекту заголовочный файл, не получается. Файл exe не видит в библиотеке функции, только классы. А через заголовочный файл вообще непонятно как работать." - в .Net каждый метод(функция) должен принадлежать определённому классу. Т.е. сами по себе методы, как в C/С++, существовать не могут, они должны быть определены в каком либо типе(классе).

    • Помечено в качестве ответа donaire 13 марта 2012 г. 8:30
    12 марта 2012 г. 20:04
    Модератор
  • Да, в этом его недостаток. Майкрософт 10 лет навязывала всем Visual Basic, а когда этого не получилось, стала навязывать NET. Для простеньких задач он подходит отлично, программирование облегчает. Но как только требуется сделать что-то более сложное, так приходится тратить втрое больше сил, чтобы не только использовать старые проверенные технологии, но ещё и преодолевать трудности, связанные с ограничениями, которые прилепили в новых. Как пример - простейшее взаимодействие форм уже требует обращения к win32 SendMessage и т.д. Без win32 никак не обойтись, однако использование её превращается в головную боль. Сейчас знакомлюсь с технологией Windows Forms, откровенно разочарован... Очередной Бейсик...

    Спасибо за ответы!

    13 марта 2012 г. 8:29
  • > простейшее взаимодействие форм уже требует обращения к win32 SendMessage и т.д. Без win32 никак не обойтись


    см. WCF; A Developer's Introduction to Windows Communication Foundation 4Samples  
       

     

    13 марта 2012 г. 8:37
  • Для общения форм внутри одного приложения в WinForms не требуется использовать SendMessage. В .NET есть свой механизм - события, делегаты. Вот статья об этом на rsdn - Делегаты и события


    Для связи [mail]

    • Помечено в качестве ответа donaire 13 марта 2012 г. 13:12
    13 марта 2012 г. 8:46
  • Да, в этом его недостаток. Майкрософт 10 лет навязывала всем Visual Basic, а когда этого не получилось, стала навязывать NET. Для простеньких задач он подходит отлично, программирование облегчает. Но как только требуется сделать что-то более сложное, так приходится тратить втрое больше сил, чтобы не только использовать старые проверенные технологии, но ещё и преодолевать трудности, связанные с ограничениями, которые прилепили в новых. Как пример - простейшее взаимодействие форм уже требует обращения к win32 SendMessage и т.д. Без win32 никак не обойтись, однако использование её превращается в головную боль. Сейчас знакомлюсь с технологией Windows Forms, откровенно разочарован... Очередной Бейсик...

    Ну, как говорится не бывает технологий и языков на все случаи жизни, каждый - для определённой области. Что касается трудностей при изучении новоых технологий, то они всегда в начале есть, и по мере продвижения вперёд их становится всё меньше. Тяжело в учении, но потом будет легче. Трудно отвыкать от старых привычек и навыков которые были до этого, но это просто вопрос времени. Что же касается платформы .NET  в целом, то на мой взгляд - это лучшее, что было придумано Microsoft за последние 10 лет. C# - элегантный, красивый и мощный язык, а программировать в  такой навороченной среде как Visual Studio, одно удовольствие. Поэтому если хотите программировать под .Net сразу переходите на C#, тем более синтаксис его очень похож на Си подобные языки, трудностей не будет. А что, касается C++, да он очень мощный язык на котором много чего можно сделать, чего не сделаешь на другом, у самого есть опыт кодирования на C++ (до перехода на .Net, особенно бесила работа с указателями, они как чёрный ящик, работаешь с ними и  не уверен что там, пока не пройдёшся отладчиком несколько раз). Програмировать для .Net можно и на C++/CLI, это всего лишь вопрос вкуса и предпочтений. Но я сразу перешёл на C#( из-за извращённого cинтаксиса C++/CLI), и не жалею. Платформа .Net реально облегчает жизнь программисту, так что, для прикладного программирования под винду это есть самое то.

       P.S. Для разработки настольных приложений есть более лучший вариант чем Windows Forms, это WPF.


    13 марта 2012 г. 9:37
    Модератор
  • Я когда-то сдуру начал программировать на Бейсике. Потом перешёл на MFC. Но пока на изучил win32, всё равно было непонятно что к чему. И много раз читал, что другие программисты тоже с этим сталкивались. классы - это оболочка, а для хорошего понимания надо знать суть того, что делаешь. А суть всё равно одна - win32 и все её функции. Да и как не зная этого, к примеру, понять то, о чём пишет Дж.Рихтер? Ну и т.д. а синтаксис C++/CLI действительно могли придумать получше.
    13 марта 2012 г. 13:11
  • Я несколько дней назад писал в теме о взаимодействии форм MDI с дочерними и в ходе обсуждения с вами пришли к выводу, что кроме SendMessage не обойтись. Из-за ошибки перекрёстных ссылок. Если мы передаём в конструкторы дочерних форм указатель на родительскую, то в родительской мы не можем хранить указатели на дочерние. Вместо них приходится использовать описатели HWND.
    13 марта 2012 г. 13:12
  • В той теме вам ответили, что можно реализовать через события. Которые events, а не Send Message. Да и сделать перекрестные ссылки из Form1 в Form2 и обратно нет никакой проблемы.

    13 марта 2012 г. 13:59
    Модератор
  • Ответил вам в той теме, с примером. Со ссылками между классами в обе стороны.
    13 марта 2012 г. 14:57
    Модератор
  • Перестаньте оффтопить, пожалуйста.

    С++/CLI - это инструмент для склеивания старого umnanaged-кода с managed. Он просто не предназначен для активной разработки UI. Если хотите писать под .net - пишите на C#. Будет меньше путаницы типа Events <-> Send Message, ссылки<->указатели. То, что вы знаете Win 32, еще не гарантирует, что вы наскоком научитесь писать на .NET. Win32 еще как-то виден при разработке под Win Forms. Но при разработке под ASP.NET/MVC,  WxF или даже SharePoint знание win32 вам почти ничем не поможет. Слишком уж глубоко он закопан :)

    13 марта 2012 г. 15:04
    Модератор