_dos_getvect, _dos_setvect 함수에 관한 질문
      글쓴이: freesky / 작성시간: 토, 2006/01/21 - 12:48오후    
  
  C로 인터럽트 처리를 공부하고 있습니다. _dos_getvect()와 _dos_setvect()함수를 사용하고 있는데요.
책에 나와 있는 예제를 한 번 만들어 보았습니다.
Shift+PrtScr 키를 5번 누르면 프로그램이 종료되는 코드입니다.
사용 컴파일러는 Borland C++ 3.1이고요.
#include <stdio.h>
#include <dos.h>
typedef void interrupt (*ISR)();
ISR org;
int count = 0;
int pressed = 0;
void interrupt myisr2()
{
	_disable();
	++count;
	_enable();
}
void interrupt myisr1()
{
	_disable();
	pressed = 1;
	_enable();
	_chain_intr(myisr2);
}
int main()
{
	org = _dos_getvect(0x5);
	_dos_setvect(0x5, myisr1);
	printf("Press <Shift + PrtScr> 5 times.\n");
	while (count < 5)
	{
		if (pressed)
		{
			printf("%dth <Shift+PrtScr> key.\n");
			pressed = 0;
		}
	}
	printf("\tYou pressed <Shift + PtrScr> 5 times.\n");
	_dos_setvect(0x5, org);
	return 0;
}
그런데 컴파일을 하면 다음 내용의 오류를 내보냅니다.
Quote:
D:\Compile\c_hard>bcc test
Borland C++ Version 3.1 Copyright (c) 1992 Borland International
test.cpp:
Error test.cpp 21: Cannot convert 'void (interrupt *)()' to 'void (interrupt far
*)(...)' in function interrupt myisr1()
Error test.cpp 21: Type mismatch in parameter '__target' in call to '_chain_intr
(void (interrupt far*)(...))' in function interrupt myisr1()
Error test.cpp 26: Cannot convert 'void (interrupt far*)(...)' to 'void (interru
pt far*)()' in function main()
Error test.cpp 27: Cannot convert 'void (interrupt *)()' to 'void (interrupt far
*)(...)' in function main()
Error test.cpp 27: Type mismatch in parameter '__isr' in call to '_dos_setvect(u
nsigned int,void (interrupt far*)(...))' in function main()
Error test.cpp 39: Cannot convert 'void (interrupt far*)()' to 'void (interrupt
far*)(...)' in function main()
Error test.cpp 39: Type mismatch in parameter '__isr' in call to '_dos_setvect(u
nsigned int,void (interrupt far*)(...))' in function main()
*** 7 errors in Compile ***Available memory 4108084
D:\Compile\c_hard>
제가 보기에는 far 포인터형과 일치하지 않아서 그렇다고 하는 것 같은데 인터넷에서 찾아봐도 어떻게 형변환을 하라는 말도 없고 코드도 모두 이런 형식이었습니다.
어떻게 하면 될까요?
그리고 추가로 getvect, setvect 함수와 _dos_getvect, _dos_setvect 함수의 차이점을 알려주시면 고맙겠습니다.
Forums: 


다음 url에서 예제 소스를 보시면 이해가 빠르실 껍니다.[url
다음 url에서 예제 소스를 보시면 이해가 빠르실 껍니다.
http://www.digitalmars.com/rtl/dos2.html#_chain_intr
덧) near, far.. 추억의 단어들이군요 :D
답변 감사합니다. 그런데 역시 안 되네요.개인적으로 좀 더 공부해
답변 감사합니다. 그런데 역시 안 되네요.
개인적으로 좀 더 공부해야겠습니다.
올해에는 꼭 노트북이 생기게 해 주세요.
myisr2, myisr1 함수를 void interrupt... 에서
myisr2, myisr1 함수를 void interrupt... 에서
void far interrupt... 으로 바꿔 주시고요.
ISR 형정의 typedef void interrupt (*ISR)();
역시 typedef void far interrupt (*ISR)();
로 바꿔 주시면 되겠습니다.
setvect 는 void far interrupt (*)() 형을 받고,
getvect 는 void far interrupt (*)() 형을 돌려주거든요.
아시다시피 near 함수 포인터와 far 함수 포인터 사이에는
모종의 자동 형변환 관계가 없습니다.
그럼 이만.
Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.
해결했습니다.dos.h 파일을 분석하니 C++용과 C용 두 가지
해결했습니다.
dos.h 파일을 분석하니 C++용과 C용 두 가지 함수가 있더군요.
#ifdef __cplusplus void _Cdecl _chain_intr ( void interrupt (far *__target)( ... )); void interrupt( far * _Cdecl _dos_getvect( unsigned __interruptno ))( ... ); void interrupt( far * _CType getvect( int __interruptno ))( ... ); void _Cdecl _dos_setvect( unsigned __interruptno, void interrupt( far *__isr )( ... )); void _CType setvect( int __interruptno, void interrupt( far *__isr )( ... )); int inline _Cdecl peek( unsigned __segment, unsigned __offset ) { return( *( (int far* )MK_FP( __segment, __offset )) ); } char inline _Cdecl peekb( unsigned __segment, unsigned __offset ) { return( *( (char far* )MK_FP( __segment, __offset )) ); } void inline _Cdecl poke( unsigned __segment, unsigned __offset, int __value ) {( *( (int far* )MK_FP( __segment, __offset )) = __value ); } void inline _Cdecl pokeb( unsigned __segment, unsigned __offset, char __value ) {( *( (char far* )MK_FP( __segment, __offset )) = __value ); } #else void _Cdecl _chain_intr ( void interrupt (far *__target)( )); void interrupt( far * _Cdecl _dos_getvect( unsigned __interruptno ))( ); void interrupt( far * _CType getvect( int __interruptno ))( ); void _Cdecl _dos_setvect( unsigned __interruptno, void interrupt( far *__isr )( )); void _CType setvect( int __interruptno, void interrupt( far *__isr )( ) );컴파일을 할 때 C++ 함수로 컴파일이 되어서 형이 맞지 않았던 것 같습니다.
myisr1()을 myisr1(...) 식으로 인터럽트 처리 관련 함수들의 형식을 모조리 바꾸니까 컴파일이 잘 됩니다.
전처리계를 잘 수정하면 될 듯한데 내공 부족으로 아직 그것까지는 모르겠군요.
어쨌든 답변 달아주신 분들, 고맙습니다.
올해에는 꼭 노트북이 생기게 해 주세요.
댓글 달기