![]() |
|
|
![]()
|
|
| Jon89 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 27.2.2012 Репутация: нет Всего: нет |
Здравствуйте всем)) Сразу говорю что я новичок и прошу не кидаться камнями за глупые вопросы.
Проблема: Надо сделать dll в fortran. Подключить ее к c#. И из с# вызвать функцию написанную в фортране. Может кто нить на пальцах объяснить как это сделать. Был бы очень признателен за примеры кода и в Fortran и в c#)))) Заранее спасибо за ответы и потраченное на меня время) |
|||
|
||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
Какой компилятор фортрана используется?
|
|||
|
||||
| Jon89 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 27.2.2012 Репутация: нет Всего: нет |
Стандартный. Не знаю как называется))
|
|||
|
||||
| FCM |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
Стандартных компиляторов не бывает. Компиляторы конкретных производителей в той или иной степени соответсвуют стандарту Фортрана, а также предлагают расширения.
Уж выясни как-нибудь, что за компилятор. Примерно - это выглядит так: Вот простейшая функция, возвращающая удвоенное значение целого аргумента для компилятора из линейки Visual Fortran.
Чтобы оформить ее в DLL, нужно создать соответствующий проект. При построении DLL-проекта будут, в частности, созданы файлы с расширением .lib и .dll. Как вызывать DLL в C# спроси на форуме по С#. А чтобы использовать DLL в С++ проекте (например, консольном проекте Microsoft Visual С++) следует обеспечить доступ С++ окружению .lib-файла на этапе компиляции, .dll-файла - на этапе выполнения. Что касается текста С++ программы, то это может быть что-то вроде:
(Обеспечить доступ к .lib-файлу можно вставив в С++ исходник директиву #pragma comment(lib, "путь_к_lib-файлу")) Это сообщение отредактировал(а) FCM - 12.3.2012, 15:54 |
||||
|
|||||
| Jon89 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 27.2.2012 Репутация: нет Всего: нет |
Попробовал сделать на с++. Пишет ошибку: Запуск программы невозможен, т.к. на компе отсутствует MSVCRTD.dll
Как посмотреть какой компилятор в Fortran у меня? Код в Fortran: INTEGER FUNCTION TWICE (X) !DEC$ ATTRIBUTES DLLEXPORT :: TWICE IMPLICIT NONE INTEGER, INTENT(IN) :: X TWICE = 2*X END FUNCTION TWICE Код в С++: #include <iostream> #pragma comment(lib, "Optim") using namespace std; extern "C" _declspec(dllimport) int TWICE(const int& x); void main() { cout<<10<<endl; cout << TWICE(1) << endl; system("pause"); } |
|||
|
||||
| FCM |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
Для начала, скажи, построил ли ты DLL по фортран-исходнику. Если да, то ругался ли (возможно в виде предупреждения) компилятор на директиву
!DEC$ ATTRIBUTES DLLEXPORT А как ты вообще с ним работаешь в Visual Studio или как-то по-другому? Если в Visual Studio, то при создании любого проекта видны все возможные компиляторы, интегрируемые в Studio. Можно также попhобовать в фортран-исходник добавить вывод специфического для компилятора макроса. Например, в консольном проекте для Intel Fortran
PS. В современном С++ функций main должна иметь тип int (а не void) и возвращать целое
|
||||
|
|||||
| Jon89 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 27.2.2012 Репутация: нет Всего: нет |
Как я понимаю, я работаю через Developer Studio (хотя в Program files программа лежит в Microsoft Visual Studio). На исходники Fortran не ругался. все нормально откомпилил. получил .dll, .lib и еще несколько файлов на выходе.
На код: PROGRAM DETECT_COMPILER WRITE(*,*) __INTEL_COMPILER END он ругается так: Compiling Fortran... C:\Program Files\Microsoft Visual Studio\MyProjects\Optim\Optim.f90 C:\Program Files\Microsoft Visual Studio\MyProjects\Optim\Optim.f90(3) : Error: Lead underscore not allowed WRITE(*,*) __INTEL_COMPILER --------------------------------^ C:\Program Files\Microsoft Visual Studio\MyProjects\Optim\Optim.f90(3) : Error: This name does not have a type, and must have an explicit type. [__INTEL_COMPILER] WRITE(*,*) __INTEL_COMPILER ----------------^ Error executing df.exe. Прикрепляю скрин из пуска. может может чем нибудь помочь в определении компилятора))) Присоединённый файл ( Кол-во скачиваний: 4 )
1.jpg 66,25 Kb |
|||
|
||||
| FCM |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
В скрине же видно, что компилятор Compaq Visual Fortran 6. Это предшественник Intel Visual Fortran. Они оба поддерживают DEC-директивы.
Это хорошо.
Точно не припомню, почему так бывает. Надо разбираться. 1) Посмотри Фортран-проект с DLL и С++ проект с консольным проектом построены ли в одном и том же режиме (либо оба в Debug, либо оба в Release)? 2) После построения DLL, как ты обеспечиваешь доступность .dll-файла использующему его С++ приложению? 3) по поводу #pragma comment(lib, "Optim") : Optim.lib находится ли в директории, автоматически просматриваемой С++ окружением в поисках lib-файлов? |
||||||
|
|||||||
| Jon89 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 27.2.2012 Репутация: нет Всего: нет |
1. Оба построены в режиме Debug
2. Я пока что в ручную копирую оба файла (lib и dll) в папку с исходниками и в Debug (Потом все прикручу к проекту) 3. Да Скачал файл MSVCRTD.dll в инете, положил в System32, но похоже он для не для моей ОС (Seven) 1. При регистрации dll в винде "regsvr32 msvcrtd.dll" вылазит: Модуль "MSVCRTD.dll" загружен, но точка входа DllregisterServer не найдена. Проверьте, что "MSVCRTD.dll" является правильным файлом Dll или OCX и повторите попытку. 2. Самое приятное что даже не регистрируя dll в системе, она работает, даже в консоли программы появляется ПРАВИЛЬНОЕ решение (умножение на 2), но в процессе запуска вылазит целая гора ошибок и предупреждений. Компиляция без ошибок. Запуск программы. Скриншот 1. Нажимаю продолжить. Скриншот 2. В консоли появляется ответ. Потом нажимаю Повтор. Скриншот 3. Нажимаю продолжить. Скриншот 4. http://imageshost.ru/photo/169495/id1768558.html http://imageshost.ru/photo/170265/id1768557.html http://imageshost.ru/photo/162667/id1768556.html http://imageshost.ru/photo/164917/id1768555.html Одно радует, что она хотя бы заработала))) Почитал в инете, данная dll связана с RunTime C++. Пробовал на XP запустить, таже фигня вылазит(( Присоединённый файл ( Кол-во скачиваний: 4 )
1.png 165,52 Kb |
|||
|
||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
По одной из приложенных картинок похоже в Compaq Fortran соглашение о вызове другое - надо бы посмотреть в свойствах проекта, если там есть такой пункт.
Попробуй в прототип фортран-функции в С++ исходнике добавить спецификацию соглашения о вызове: __stdcall
Можно еще попробовать явно устанавливать соглашение о вызове в фортран-исходнике с помощью DEC-директив. PS/ Вот еще тут посмотри http://forum.sources.ru/index.php?showtopic=351171 Это сообщение отредактировал(а) FCM - 15.3.2012, 17:53 |
|||
|
||||
| Jon89 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 27.2.2012 Репутация: нет Всего: нет |
Огромное спасибо) в с++ заработало. кинул библиотеку MSVCRTD.dll прям в папку с исходниками, чтоб system32 не засорять
Только осталось 2 проблемки - в x64 не робит данная библиотека. а в инете только такая версия. все перерыл уже - когда в с# пытаюсь тоже самое сделать, он ругается (строка вызова Twice(2)): Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена. Исходники с#: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsFormsApplication1 { public partial class Form1 : Form { [DllImport("Optim.dll", CallingConvention = CallingConvention.StdCall)] public static extern int TWICE(int A); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { int b; b = TWICE(2); int c = b; } } } Это сообщение отредактировал(а) Jon89 - 18.3.2012, 10:13 |
|||
|
||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: 8 Всего: 9 |
По использованию DLL в C# лучше спроси в соответствующем форуме.
Если будет не лень, после того как заработает отпишись, как должна выглядеть соответствующая С# программа - пригодится кому-нибудь в будущем. |
|||
|
||||
| Jon89 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 8 Регистрация: 27.2.2012 Репутация: нет Всего: нет |
Рабочий код в С#:
using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsFormsApplication1 { public partial class Form1 : Form { [DllImport("Optim.dll")] public extern static int TWICE(ref int A); public Form1() {InitializeComponent();} private void button1_Click(object sender, EventArgs e) { int a = 3; textBox1.Text = TWICE(ref a).ToString(); } } } FCM, спасибо за помощь с кодом С++))) |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Fortran | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |