2016-09-17 3 views
0

그래서 외부 스크립팅 언어를 사용하지 않고 런타임 중에 내 응용 프로그램의 동작을 변경하고 싶습니다. DLL을 사용해 보았습니다. 나는 다음과 같은 것을 가지고있다 :C에서 스와핑하는 DLL이 잘못 되었습니까?

begin program; 
load dll and function pointers; 
init_func_ptr(); 
loop: 
    if(compiled_new_version) 
    { 
     pause threads; 
     unload dll; 
     overwrite expired dll with new dll; 
     load dll and function pointers; 
     resume threads; 
    } 
    update_func_ptr(state); 

초기에는 아무런 문제가 없었다. 그러나 일단 실제 코드를 작성했다면 dll을 다시로드 한 후 충돌이 발생했습니다. 수동으로 내보내거나 다시로드하는 함수 포인터 만 'init'및 update '입니다.

충돌에 대한 정보가 있습니다. 아무 곳에도 충돌이 발생합니다. 호출 스택에는 '0xCDCDCDCD'라는 주소가 있습니다 (Visual Studio를 디버거로 사용하고 응용 프로그램이 디버그 모드로 컴파일 될 때 발생합니다).

나는 스레드를 일시 중지하면 그 중 하나 이상이 만료 된 DLL 내에서 일부 코드를 실행하므로 해당 DLL을 언로드하고 스레드를 다시 시작하면 충돌이 발생합니다.

이 문제를 어떻게 해결할 수 있습니까?

+0

의사 코드를 게시하지 말고 ** 실제 ** 코드의 [mcve]를 게시하십시오. [ask] – Olaf

답변

2

DLL을 언로드하는 것이 안전한지 확인하기 위해 DLL에 코드를 작성해야 할 수 있습니다. 예를 들어, 입력시 모든 함수는 DLL 전역 변수를 증가시키고 종료시 감소시킵니다. 0 일 때만 DLL을 안전하게 언로드 할 수 있습니다.

DLL이 "종료 모드"이며 더 이상 호출되지 않아야한다는 것을 관리하는 코드를 작성해야 할 수도 있습니다. 예를 들어 DLL이 다시로드 될 때까지 호출 스레드를 일시 중지 할 수있는 모든 내 보낸 함수에 대한 래퍼가있는 래퍼 모듈. 이 모듈은 DLL 자체에있을 수 없습니다.

먼저 카운팅, 동기화 및 로딩을위한 최소한의 기능을 포함하는 개념을 테스트하기위한 스켈레톤 응용 프로그램을 만드는 것이 좋습니다.

+0

참고 슬프게도 GetQueuedCompletionStatus에서 대기하는 I/O 완료 스레드가 있습니다. 이러한 스레드를 실행 파일에 배치하고 언로드하는 동안 해당 스레드가 DLL 함수를 호출하지 않도록하여 문제를 해결할 수 있습니까? – AcarX

+1

DLL을 호출하지 않는 한 안전하게 언로드/다시로드 할 수 있습니다. '0xcdcdccd'는 VS 디버그 초기화되지 않은 메모리의 전형입니다. –

+0

대답 해 주셔서 감사합니다. 계속해서 시도해보고 다시보고 할 것입니다. – AcarX