Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [General] Вызов DLL из программы. 
V
    Опции темы
Karabas
Дата 12.7.2006, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 14.6.2006

Репутация: нет
Всего: нет



Я понимаю, избитый вопрос, но тем не менее ответ все еще не ясен. 

Как вызвать функцию dll из программы на фортране? 
Я использую Fortran power station 4, но обсуждения о других весиях тоже не дают ответа. 

Типичный ответ на такой вопрос (либо в хелпе, либо на форумах): 
Сделатаь ДЛЛ из файла f90vb4.f90 : 
Код

SUBROUTINE ARRAYTEST(arr)
   !MS$ATTRIBUTES DLLEXPORT :: ARRAYTEST
   REAL(4)  arr(3, 7)
   INTEGER i, j
   DO i = 1, 3
      DO j = 1, 7
         arr (i, j) = 11.0 * i + j
      END DO
   END DO
END SUBROUTINE

you can compile from the command line with:
fl32 /LD f90vb4.f90
which creates a DLL named f90vb4.dll.

Вызвать функцию из ДЛЛ: 
Код

      PROGRAM FORAPP
      REAL r1, r2, xarray(3, 7)
      ...
      INTERFACE
         SUBROUTINE ARRAYTEST (rarray)
            !MS$ATTRIBUTES DLLIMPORT :: ARRAYTEST 
            REAL rarray(3, 7) 
         END SUBROUTINE ARRAYTEST
      END INTERFACE
      ...
      CALL ARRAYTEST(xarray)
      ...
      END


Но где же в этой программе вызова указано ИМЯ(!) нужной dll библиотеки? А если у меня библиотек несколько и вызвать мне надо вполне определенную функцию из определенной ДЛЛ? 
И действительно, при попытка скомпилить этот пример компилятор отвечает, что не знает external функции ARRAYTEST , и чисто по-человечески я могу его (компилятор) понять. 

Либо из этого примера выкинули нечто важное, либо существуют некие правила, используемые фортраном по умолчанию, и которые я не знаю..  
Помогите, пожалуйста, если кто сталкивался.  
PM MAIL   Вверх
Cr@$h
Дата 12.7.2006, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
***


Профиль
Группа: Участник Клуба
Сообщений: 1693
Регистрация: 3.4.2005
Где: Санкт-Петербург, Россия

Репутация: 1
Всего: 41



Цитата(Karabas @  12.7.2006,  10:57 Найти цитируемый пост)
И действительно, при попытка скомпилить этот пример компилятор отвечает, что не знает external функции ARRAYTEST , и чисто по-человечески я могу его (компилятор) понять. 

Дело в том, что как и большинство програмистов, ты используешь неявное подключение процедур из DLL. Здесь ты не используешь никаких Win API функций типа LoadLibrary, а передаешь все действия по подключению компилятору (точнее компоновщику -- linker'у).
При неявном подключении (implicit linking) компоновщику передается библиотека импорта (обычно имеет расширение lib), содержащая список переменных и функций DLL, которые могут использовать приложения. Обнаружив, что программа обращается хотя бы к одной из них, компоновщик добавляет в целевой exe-файл таблицу импорта. Таблица импорта содержит список всех DLL, которые использует программа, с указанием конкретных переменных и функций, к которым она обращается. Позже, когда exe-файл будет запущен, загрузчик проецирует все DLL, перечисленные в таблице импорта, на адресное пространство процесса; в случае неудачи весь процесс немедленно завершается.
При компиляции указанной DLL будет создано два файла: *.dll и *.lib. При создании проекта, использующего DLL, ты должен подключить к нему эту библиотеку импорта *.lib и, естественно, держать саму DLL "неподалеку", например в директории с *.exe файлом (есть определённые правила, по которым ищется DLL).
Цитата

Add the import .LIB file with its path and library name to the other image. 
In the integrated development environment, add the .LIB import library file to your project. In the Project menu, select Add Existing Item.... If the importing project and the DLL are in the same solution, you can add the DLL project as a dependency of the importing project instead.

On the command line, specify the .LIB file on the command line.

The import .LIB file contains information that your program needs to work with the DLL.

Напишу подробности из одного места.

Порядок использования DLL
  • Подключение библиотеки импорта.
    Все, что вам нужно – это передать линкеру (компоновщику) имя библиотеки импорта, чтобы он использовал ее в процессе сборки. Сделать это можно различными способами.
    • Если импортирующий процедуры проект и DLL находятся в одном решении, можно добавить проект DLL как зависимость для основного проекта (Add dependency... ( smile )).
    • Можно непосредственно добавить файл *.lib в проект Visual Studio посредством команды Project > Add Existing Item….
    • Можно указать имя библиотеки импорта в опциях линкера. Для этого нужно открыть окно настроек проекта (Project > Properties…) и добавить в поле Aditional Options на вкладке Linker\Command Line имя *.lib.
    • Если используется другая среда или консольный компилятор, то можно указать имя библиотеки импорта в аналогичном месте или добавить *.lib в строку компоновки проекта, соответственно.
    • Наконец, можно встроить ссылку на библиотеку импорта прямо в исходный код программы, используя соответствующие директивы, например #include.
  • Написание интерфейсов к используемым процедурам.
    Эти интерфейсы удобнее всего оформлять как отдельные заголовочные файлы или модули. Благодаря неявному подключению достаточно просто написать заголовки процедур на используемом языке и удовлетворить соглашения о вызовах с помощью директив и опций компилятора.
    После написание интерфейсов к процедурам их можно начать использовать в коде, т.к. компилятор будет знать, что они внешние.
    Совет: если разрабатывается решение, в котором многие проекты используют библиотеку, то удобнее размещать библиотеку импорта и файл интерфейсов в его директории, чем дублировать в директории каждого проекта.
  • Размещение самой .dll в директории с исполняемым файлом.
    Обычно это директории типа Debug, Release, Bin. В принципе, при запуске приложения будет сообщено, что библиотека не может быть найдена. Существует определенный порядок, в котором производится поиск файла библиотеки. Рекомендуется все же размещать именно в директории с исполняемым файлом, т.к. это позволит избежать возможных коллизий.

Цитата

Но где же в этой программе вызова указано ИМЯ(!) нужной dll библиотеки? А если у меня библиотек несколько и вызвать мне надо вполне определенную функцию из определенной ДЛЛ? 

Используй ты явное подключение тебе бы пришлось указывать имя файла библиотеки, процедуру из которой ты используешь. При явном подключении (explicit linking) приложение вызывает функцию LoadLibrary, чтобы загрузить DLL, затем использует функцию GetProcAddress, чтобы получить указатели на требуемые функции (или переменные), а по окончании работы с ними вызывает FreeLibrary, чтобы выгрузить библиотеку и освободить занимаемые ею ресурсы. Это всё прописывается руками.
При неявном подключении всё это делает компоновщик, а ты только указываешь *.lib файл бибилотеки. Но и здесь возникает законный вопрос: "Есть две DLL, в которых есть процедуры с одинаковыми именами. Обе DLL подключены неявно к проекту с помощью добавления к нему файлов *.lib. Как указать, из какой из двух библиотек используется процедура, имя которой присутствует в обоих?".  smile smile  smile  smile 
Может, этого нельзя делать? Если, скажем, у нас прога использует два модуля, которые содержать две процедуры с одним именем, то при использовании этого имени в проге компилятор заругается. Может, также и здесь: два файла *.lib содержат используемое имя, и у компилятора глаза разбегаются в разные стороны.
Возможно, с помощью Win API функций это можно будет делать, ведь там указывается конкретное имя библиотеки... Но тогда процедурам, если они обе будут использоваться, нужно будет давать разные псевдонимы.
Я ещё подумаю над этим вопросом. smile  smile  
PM MAIL ICQ   Вверх
Cr@$h
Дата 13.7.2006, 06:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
***


Профиль
Группа: Участник Клуба
Сообщений: 1693
Регистрация: 3.4.2005
Где: Санкт-Петербург, Россия

Репутация: 1
Всего: 41



Надеюсь, с "Вызовом DLL из программы на фортране" автору топика теперь прояснилось.

Вопрос коллизии имён процедур при использовании не одной DLL несколько выходит за рамки данной темы. Ведь эта проблема решается как при неявном (статическом), так и при явном (динамическом) подключении. Здесь же я рассказал, что не доставало Karabas при неявном подключении, и, если что-то осталось за кадром, можно продолжить дискуссию. Про то, как же подключать несколько DLL, содержащих процедуры с одинаковыми именами, предлагаю обсуждать в новой теме, т.к. эта проблема может заинтересовать многих и не отражёна в названии этого топика. 
PM MAIL ICQ   Вверх
Karabas
Дата 13.7.2006, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 14.6.2006

Репутация: нет
Всего: нет



Спасибо, Cr@$h, заработало.   smile 
Теперь я понял, каким образом мой компилятор знает, что надо использовать внешнюю библиотеку. 
Я ОБЯЗАН ему это сообщить, путем включения в мой проект файла lib соответствующей библиотеки. Надо внимательнее читать мануал..  smile 

Как я понимаю, отсюда следует слудующий вывод: 
Если есть готовая библиотека dll,  то вовсе не факт, что я смогу ее использовать в своем проекте. 
То есть можно рассчитывать только на свои силы..  smile 
Вообще-то с точки зрения копирайта это имеет смысл, но неужели это действительно так? 
Я попробовал подключить сразу dll библиотеку к моему проекту -- не пошло. Требует lib. 

Да, и еще вопрос (я рабою только на фортране, кто знает -- просветите), при создании длл в других языках создается такой же файл .lib с синтаксисом идентичным фортраноскому? Другими словами, .lib -- это общий стандарт или все зависит от компилятора? 
 
PM MAIL   Вверх
Cr@$h
Дата 13.7.2006, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
***


Профиль
Группа: Участник Клуба
Сообщений: 1693
Регистрация: 3.4.2005
Где: Санкт-Петербург, Россия

Репутация: 1
Всего: 41



Цитата(Karabas @  13.7.2006,  12:52 Найти цитируемый пост)
Если есть готовая библиотека dll,  то вовсе не факт, что я смогу ее использовать в своем проекте. 

Почему. Всегда можно. Для этого нужно знать используемые DLL соглашения о вызовах и имена экспортируемых процедур. Последние можно узнать, используя специальные утилиты. В IFVC 9.1 пишут про DUMPBIN:
Цитата

Checking the DLL Symbol Export Table
To make sure that everything that you want to be visible shows up in the export table, look at the export information of an existing DLL file by using QuickView in the Windows Explorer File menu or the following DUMPBIN command:
Код

DUMPBIN /exports file.dll


Если с DLL идёт библиотека импорта .lib, радуйся -- можешь использовать статическое (неявное подключение). В этом случае потребуется только описать интерфейсы внешних процедур. Если lib'а не идёт -- Win API тебе придётся юзать. В соседней теме можешь, например посмотреть. Тоже ничего сложного на самом деле.
Цитата(Karabas @  13.7.2006,  12:52 Найти цитируемый пост)
То есть можно рассчитывать только на свои силы..   
Вообще-то с точки зрения копирайта это имеет смысл, но неужели это действительно так?

Не совсем уловил  мысль smile 
Цитата(Karabas @  13.7.2006,  12:52 Найти цитируемый пост)
Я попробовал подключить сразу dll библиотеку к моему проекту -- не пошло. Требует lib.

Посмотри пример в созданной теме. Кидаешь DLL в папку с exe'шником, в коде используешь Win API процедуры. Если возникнут непонятки, можешь создать тему именно про "Динамическое подключение DLL в Fortran |явное использование Win API процедур|". Эта пока больше про статическое (неявное) подключение.
Цитата(Karabas @  13.7.2006,  12:52 Найти цитируемый пост)
Да, и еще вопрос (я рабою только на фортране, кто знает -- просветите), при создании длл в других языках создается такой же файл .lib с синтаксисом идентичным фортраноскому? Другими словами, .lib -- это общий стандарт или все зависит от компилятора? 

По идее, он зависит от платформы: под виндамии на IA-32 всё должно быть едино. .obj файлы могут различаться у компиляторов и то не факт. Я занимался системным программированием, раньше стандарта чёткого не существовало, большинство любили формат obj от IBM. Сейчас мы живём в XXI веке и, думаю, здесь давно всё нормально. Специально искал инфу по этому делу, но нашёл в MSDN только это:
Цитата

Import libraries contain information about exports in other programs and are created either by LINK when it builds a program that contains exports or by the LIB tool.

По секрету говоря, IVFC (Intel Visual Fortran Compiler) использует link'ер от Microsoft'а. Для FPS, DVF, CVF это аналогично, ведь все сидят в одной IDE Developer Studio.
При создании DLL на Fortran использовал их на С++ в VS вместе с созданными .lib -- и ничего, всё нормально. .lib это как .dll и .exe -- на одной оси для IA-32 (Intel 32-совместимых процов) они создаются по одним незыблемым правилам. Думаю, я ответил на вопрос. 
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Fortran | Следующая тема »


 




[ Время генерации скрипта: 0.1232 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.