Продолжение - дальнейшие извращения с 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;
}
|