이전에 lf90으로 컴파일 한 서브 루틴 sendmsg.f90을 gcc가 64 비트 인 32 비트로 컴파일하려고합니다. 그 목적은 gcc로 컴파일 된 다른 64 비트 서브 루틴과 링크하는 것입니다. gcc (gfortran)로 컴파일 할 때 windows API 함수 (64 비트)를 호출 할 수 있습니까?
subroutine UpdateDisplay(WINHAND,NTPS,QCANCEL,NITER)
use win32mod
implicit none
integer WINHAND, NTPS, MESSNUM, NITER, QCANCEL
! SendMessageA is a Windows function
! WINHAND = handle of window (from ISDev code)
! MESSNUM = message number (assigned by ISDev)
! NTPS = number of year iteration currently on (WParam)
! DUM = 0 (LParam)
MESSNUM = 1114
QCANCEL = SendMessageA(carg(WINHAND),carg(MESSNUM),carg(NTPS), carg(NITER))
end subroutine
우리는 lf90 컴파일러와 GCC (gfortran을 사용하는) 무엇인가라는 LGF 가지고있는 Lahey 포트란 7.5이 (내가 GCC를 사용한다고 가정 권리이다?)를.
저는 Windows 프로그래밍 (및 포트란)을 처음 사용합니다. gcc로 컴파일 된 코드는 Windows API를 호출 할 수 있습니까? ISO_C_BINDING을 사용해야합니까?
gcc에서 만든 .o 파일과 lf90으로 만든 .obj 파일을 연결해야합니까?
도움 주셔서 감사합니다.
업데이트 : 내가 가진 윈도우 API를 호출 시도했다 :
MODULE SND_C
interface
integer(C_LONG) FUNCTION SendMessage &
(WINHAND,MESSNUM,NTPS, NITER) &
bind(C,Name='SendMessage')
use ISO_C_BINDING
implicit NONE
integer(C_LONG), VALUE :: WINHAND
integer(C_LONG), VALUE :: MESSNUM
integer(C_LONG), VALUE :: NTPS
integer(C_LONG), VALUE :: NITER
end function SendMessage
end interface
END MODULE SND_C
subroutine UpdateDisplay(WINHAND,NTPS,QCANCEL,NITER)
USE ISO_C_BINDING, ONLY: C_LONG
USE SND_C
implicit none
integer(C_LONG) WINHAND, NTPS, MESSNUM, NITER, QCANCEL
! SendMessageA is a Windows function
! WINHAND = handle of window (from ISDev code)
! MESSNUM = message number (assigned by ISDev)
! NTPS = number of year iteration currently on (WParam)
! DUM = 0 (LParam)
!GCC$ ATTRIBUTES DLLEXPORT :: UpdateDisplay
MESSNUM = 1114
QCANCEL = SendMessage(WINHAND,MESSNUM,NTPS, NITER)
end subroutine
을하지만 컴파일 할 때 "GCC -m64 sendmsg.f90"나는 오류 얻을 :
C:\Users\StephanieJ\Documents\Lahey-Fujitsu Fortran>gcc -m64 sendmsg.f90
c:/progra~2/lahey-~1/v7.5/gcc-gf~1/bin/../lib/gcc/x86_64-w64-mingw32/4.7.4/../..
/../../x86_64-w64-mingw32/lib/../lib/crt2.o: In function `__tmainCRTStartup':
c:\gccbuild\mingw-crt\build32-64\mingw-w64-crt/../../mingwsvn/mingw-w64-crt/crt/
crtexe.c:323: undefined reference to `__laheypause'
C:\Users\STEPHA~2\AppData\Local\Temp\ccWjjo5b.o:sendmsg.f90:(.text+0x3e): undefi
ned reference to `SendMessage'
c:/progra~2/lahey-~1/v7.5/gcc-gf~1/bin/../lib/gcc/x86_64-w64-mingw32/4.7.4/../..
/../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o):
In function `main':
c:\gccbuild\mingw-crt\build32-64\mingw-w64-crt/../../mingwsvn/mingw-w64-crt/crt/
crt0_c.c:18: undefined reference to `WinMain'
collect2.exe: error: ld returned 1 exit status
을
이 방법이 의미가 있습니까? SendMessage에 대한 참조가 정의되지 않은 이유는 무엇입니까?
#include <windows.h>
void updatedisplay_( HWND *winhand, WPARAM *ntps, LRESULT *qcancel, LPARAM *niter)
{
// integer NTPS, MESSNUM, NITER, QCANCEL
/*
! WINHAND = handle of window (from ISDev code)
! MESSNUM = message number (assigned by ISDev)
! NTPS = number of year iteration currently on (WParam)
! DUM = 0 (LParam)
*/
UINT messnum = 1114;
*qcancel = SendMessage(*winhand,messnum,*ntps,*niter);
}
낮은 경우와 후행는 포트란 기본 기능 이름과 일치하도록되어 밑줄 : API를 호출하는
Fortran에서 Windows 64 비트 API를 호출 할 수 있지만 API가 변경되었음을 인식해야하며 [ABI] (https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention)도 알고 있어야합니다. 특정 인터페이스 (windows.h와 같은 의미)가 필요합니다. –
64 비트에서 STDCALL에 대해 걱정할 필요가 없으므로 실제로 API 루틴을 호출하는 것이 더 쉽습니다. 필요한 것은 적절한 인터페이스이며, BIND (C)를 사용하여 대소 문자를 혼합 한 이름을 지정할 수 있습니다. ISO_C_BINDING을 (를) 사용하면 종류 값에 도움이되지만 그다지 도움이되지 않을 수 있습니다. 인텔 포트란은 수천 가지 Windows API 루틴에 대한 선언을 제공합니다. 다른 Windows 컴파일러에서도 마찬가지입니다. –
아마 SendMessageA 여야합니까? Windows API에서 일반적으로 문자를 다루는 함수는 A (ANSI charset)로 끝나는 버전과 W (와이드, 즉 유니 코드)로 끝나는 버전 두 가지가 있습니다. C 언어에서는 다른 언어를 호출 할 때가 아니라 자동으로 이름이 선택됩니다 (아마도 windows.h의 macris로). –