_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용 두 가지 함수가 있더군요.
컴파일을 할 때 C++ 함수로 컴파일이 되어서 형이 맞지 않았던 것 같습니다.
myisr1()을 myisr1(...) 식으로 인터럽트 처리 관련 함수들의 형식을 모조리 바꾸니까 컴파일이 잘 됩니다.
전처리계를 잘 수정하면 될 듯한데 내공 부족으로 아직 그것까지는 모르겠군요.
어쨌든 답변 달아주신 분들, 고맙습니다.
올해에는 꼭 노트북이 생기게 해 주세요.
댓글 달기