Подключение DLL на фортране к проекту C++
От: Pavel_O Россия  
Дата: 14.05.07 10:33
Оценка:
Здравствуйте.
Мне необходимо подключить DLL библиотеку написанную на фортране (библиотека скомпилина в MS FORTRAN 5.1 с одним внешним SUBROUTINE).

В этой библиотеке мне необходимо задать около 200 переменных, описанных в COMMON блоках.

например
COMMON /O1/ P1, P2, P3(5)


в основной программе описана структура
struct
{
 float 
  P1,
  P2,
  P3[5];
} O1;


Я хочу задать переменные в DLL явно к ней подключившись.

HMODULE hLib;
hLib = LoadLibrary("MyDll.dll");



Собственно возникло 2 вопроса
1) Могу ли я таким образом задаваь переменые?

int *pVar;
(FARPROC &)pVar = GetProcAddress(hLib, "P1");
*pVar = O1.P1;

2) Могу ли я передать структуру и присвоить ее блоку COMMON

int *pVar;
(FARPROC &)pVar = GetProcAddress(hLib, "/O1/");
*pVar = O1;


Пожалуйста подскажите.
Re: Подключение DLL на фортране к проекту C++
От: Privalov  
Дата: 15.05.07 05:37
Оценка:
Здравствуйте, Pavel_O, Вы писали:

P_O>Здравствуйте.

P_O>Мне необходимо подключить DLL библиотеку написанную на фортране (библиотека скомпилина в MS FORTRAN 5.1 с одним внешним SUBROUTINE).

А он разве умеет 32-битовые DLL строить? Если не ошибаюсь, FORTRAN 5.1 выпущен где-то в 90-м или 91-м году.

P_O>В этой библиотеке мне необходимо задать около 200 переменных, описанных в COMMON блоках.


Когда в FORTRAN-е объявляется COMMON-блок, снаружи видно только его имя, а не его составляющих.
Мне в свое время приходилось связывать модули, написанные на C и на FORTRAN-е, кажется, этом же 5.1 или 5.0.
Если в FORTRAN-овской программе был объявлен COMMON-блок

P_O>например

P_O>
P_O>COMMON /O1/ P1, P2, P3(5)
P_O>


то в C-программе я делал так:

struct _O1
{
   float P1, P2, P3;
}

extern fortran _O1 O1;


У меня была не DLL, я все собирал в один EXE.


P_O>в основной программе описана структура

P_O>
P_O>struct
P_O>{
P_O> float 
P_O>  P1,
P_O>  P2,
P_O>  P3[5];
P_O>} O1;
P_O>


P_O>1) Могу ли я таким образом задаваь переменые?


P_O>
P_O>int *pVar;
P_O>(FARPROC &)pVar = GetProcAddress(hLib, "P1");
P_O>*pVar = O1.P1;
P_O>


Так — нет. Снаружи видно только имя COMMON-блока, а не его членов. Имя P1 никому ничего не скажет.

P_O>2) Могу ли я передать структуру и присвоить ее блоку COMMON


Тут нужен указатель не на int, а на структуру, которая COMMON-блок описывает. Тогда у тебя будет нормальный доступ к ее членам.

P_O>
P_O>int *pVar;
P_O>(FARPROC &)pVar = GetProcAddress(hLib, "/O1/");
P_O>*pVar = O1;
P_O>


Сдается мне, надо несколько иначе:

P_O>
P_O>O1 *pVar;
P_O>pVar = (_O1 *)GetProcAddress(hLib, "O1");
P_O>


Дальше в C-программе можно делать, как обычно:
extern fortran _O1 O1;

//............

float f()
{
  O1->P1 = 0.0f;
  return O1->P1;
}


Не уверен насчет синтаксиса C#.

Еще один момент — соглашения о связях. Я не знаю, что скажет C# при вызове функции из такой DLL. Необходимо проверять.

Ну, и то, что я тут спросонок понаписал, нужно как следует проверить. У меня под рукой нет компилятора FORTRAN. Поэтому сам не могу.
Удачи!
Re[2]: Подключение DLL на фортране к проекту C++
От: Pavel Dvorkin Россия  
Дата: 15.05.07 08:09
Оценка:
Здравствуйте, Privalov, Вы писали:

P>А он разве умеет 32-битовые DLL строить? Если не ошибаюсь, FORTRAN 5.1 выпущен где-то в 90-м или 91-м году.


Compaq Fortran 6.5 интегрируется в DevStudio 6 и вполне нормально там живет. 32 бита, естественно.

По существу вопроса ответить не могу, но могу выслать документацию. 9 Мб , 3 pdf.
With best regards
Pavel Dvorkin
Re[2]: Подключение DLL на фортране к проекту C++
От: Pavel_O Россия  
Дата: 15.05.07 09:53
Оценка:
Здравствуйте, Privalov, Вы писали:

P>А он разве умеет 32-битовые DLL строить? Если не ошибаюсь, FORTRAN 5.1 выпущен где-то в 90-м или 91-м году.

Да, FORTRAN 5.1 не умеет строить 32 DLL. Поэтому я собрал новую библиотеку в Intel Fortran

P>extern fortran _O1 O1;
P>

"Директива _fortran больше не поддерживается. Для функций ее необходимо заменить на __stdcall."

P>У меня была не DLL, я все собирал в один EXE.

а не могли бы Вы описать это подробнее? Или дать ссылку на пример, документацию.. Именно сборки фортрана и С.

P>Сдается мне, надо несколько иначе:

P_O>>
P_O>>O1 *pVar;
P_O>>pVar = (_O1 *)GetProcAddress(hLib, "O1");
P_O>>

Вызов GetProcAddress возвращает пустой адрес.

По сути, различия между C# и C++ в данный момент меня не волнуют, т.к. могу делать там и там.
Re[3]: Подключение DLL на фортране к проекту C++
От: Pavel_O Россия  
Дата: 15.05.07 09:54
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>По существу вопроса ответить не могу, но могу выслать документацию. 9 Мб , 3 pdf.


Вышлите пожалуйста на oca@planetwork.ru
Re[3]: Подключение DLL на фортране к проекту C++
От: Privalov  
Дата: 15.05.07 09:57
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Compaq Fortran 6.5 интегрируется в DevStudio 6 и вполне нормально там живет. 32 бита, естественно.


Это понятно. Но в исходном сообщении сказано следующее:

Мне необходимо подключить DLL библиотеку написанную на фортране (библиотека скомпилина в MS FORTRAN 5.1 с одним внешним SUBROUTINE).


и поэтому возникают сомнения по поводу 32-битности.
Re[3]: Подключение DLL на фортране к проекту C++
От: Privalov  
Дата: 15.05.07 11:13
Оценка:
Здравствуйте, Pavel_O, Вы писали:

P_O>"Директива _fortran больше не поддерживается. Для функций ее необходимо заменить на __stdcall."


Значит, отстал я от жизни. Да, здесь речь идет не о функции, а о глобальной переменной, к тому же, сидящей в DLL. Так что тут особо можно не волноваться. Там дальше GetProcAddress пустой адрес возвращает, так это из-за того, что имя неправильно указано, возможно, его экспортировать надо.


P_O>а не могли бы Вы описать это подробнее? Или дать ссылку на пример, документацию.. Именно сборки фортрана и С.


Делал я эту сборку очень давно. Использовал MS FORTRAN 5.x MS и C 6.0 (не Visual!). Все делал в среде MS DOS.
Всю информацию добыл из документации к C и FORTRAN, попавшую к нам в бумажном виде из Болгарии (Правец-16 слышал? ), протоколов трансляции и сборки. Даже подробно это записал (нужно было для отчета по теме в НИИ, где я тогда работал). Попробую дома поискать вечером, правда, шансов немного: диски менял несколько раз и т. п. Обнадеживать не буду.

Поскольку я делал один EXE, выглядело это примерно так:

   COMMON /CA/ A, B, C

   SUBROUTINE FA(W)
   REAL W
   .......
   RETURN
   END



struct A
{
   float a;
   float b;
   float c;
}

extern fortran A CA;

void fortran fa(float w);

void main()
{
   float a = 0.0f;

   fa(a);
}


Make-файл создавался в среде Programmer's WorkBench автоматически. Собственно, эту среду я использоват только и исключительно для создания make-файлов, она слишком неповоротлива для работы.
В случае с DLL достаточно получить адрес COMMON-блока.

Грабли со строками из-за разной трактовки строк в C и FORTRANе. Обходится, в общем, просто, но деталей уже не помню, а вводить в заблуждение не хочется.
Вообще, там все сложности — технические. Если доступны все исходники, то все решается правильными объявлениями, экспортом, установкой атрибутов.

P_O>Вызов GetProcAddress возвращает пустой адрес.


См. выше.

Еще раз удачи. И тщательно проверь, чего я настрочил. Правда, уже я проснулся и даже приступил к работе.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.