Продолжение - дальнейшие извращения с DLL на Fortran и динамического вызова ее из программы на BUILDER C++, на этот раз с передачей адресов функций и взаимовызовом:)


Функция на Фортране, тип проекта - Fortran DLL


subroutine Dll(a,b)
  ! Expose subroutine Dll to users of this DLL
  !
  !DEC$ ATTRIBUTES DLLEXPORT::Dll
  
  integer a(10)
  real b
  integer arr(10)
  common /common/ arr
  !DEC$ ATTRIBUTES DLLEXPORT::common
  b=sin(b)
  arr=10
  a=a+b
end subroutine Dll

integer function dll_f(func,arg)
interface 
 real function func(real)
 end function func 
end interface
real arg
!DEC$ Attributes dllexport::dll_f
print *,"before"
pause
    dll_f=func(arg);
end
Вызов на C++ Embarcadero BUILDER, тип проекта - console

#include 
#pragma hdrstop
#pragma argsused

#include 
#include 

typedef	void (*FP)(int * a,float *b);
typedef	int (*FP1)(float(*)(float arg),float);
int * common;


float func(float arg)
{
 return arg;
}


int _tmain(int argc, _TCHAR* argv[])
{
   HMODULE dll;
   FP fp;
   FP1 fp1;
   int a[10];
   float b=1;
   for (int i = 0; i < 10; i++) a[i]=i-10;

   dll=LoadLibrary(TEXT("dll.dll"));
   if(!dll)
   {
	puts("DLL.dll не загружена");
	return GetLastError();
   }
   fp=(FP)GetProcAddress(dll,"DLL");
   fp1=(FP1)GetProcAddress(dll,"DLL_F");
   common=(int *)GetProcAddress(dll,"COMMON");
   if (fp!=NULL || fp!=NULL || common==NULL)
   {
	 float tmp;
		fp(a,&b);
		tmp=2.7;
// вызовем функцию из Фортрана, передав ей в качестве первого параметра
// адрес "местной" функции, которая будет вызвана оттуда.
		a[0]=fp1(func,25.);

		a[0]=common[0];
   }
   else
   {
	puts("Ошибка получения адреса функции");
	return GetLastError();
   }
	// Отключаем библиотеку
   if(!FreeLibrary(dll))
   {
	puts("Ошибка выгрузки библиотеки из памяти");
	return GetLastError();
   }
   return 0;
}