2013-06-03 2 views
0

함수 포인터를 인수로 받아서 함수 포인터를 아래와 같이 호출합니다. C++ 콜백 함수 런타임 오류

int foo (int a, int(*calc)(int)) 
{ 
    int y; 
    // .... 
    // calling calc function via callback 
    (*calc)(y); 
} 

석회질 기능

a.cpp에 배치됩니다

int calc(int x) 
{ 
    // .... 
    cout << x; 
    checkValue(x); 
} 

기능 foo과 기능 calc()checkValue()이 파일 b.cppc.cpp에 정의되어 같은 모습을 다시 호출 할 수 있습니다. 내 문제는 calc()cout 진술 때까지 실행하고 checkValue() 함수를 호출하는 데 실패합니다. 내가받은 오류 보고서는 다음과 같습니다.

symbol lookup error:..... undefined symbol: _ZNSaIcEC1Ev, version GLIBCXX_3.4 

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

+0

디버거와 함께 실행하여 충돌이있는 곳을 정확히 알아냅니다. 그것은'checkValue()'를 호출하지만 다른 곳에서는 충돌합니다. 'foo'의 코드를 더 포함하고'checkValue()'의 코드를 포함 시키십시오. 왜냐하면 그 함수 중 하나에서 충돌하기 때문입니다. –

+1

"ldd -r/path/to/your/programm"또는 "readelf -d/path/to/your/programm | grep PATH"를 실행하면 libstdC++의 어떤 버전이 표시됩니까? –

+1

endl; 귀하의 계산 기능에 귀하의 cout 진술 후. 스트림을 플러시하지 않기 때문에이 출력이 표시되지 않을 수 있습니다. 또는 디버거를 사용하여 checkValue (x) 행에 도달하지 않았는지 확인하십시오. – ChrisCM

답변

0

... 거기에있을 수 있습니다 (I 결정 이것은 c++filt(1) 프로그램을 사용하여). 오류 메시지 "symbol lookup error:..... undefined symbol"은 동적 연결과 관련이 있으며 함수 포인터를 통해 함수를 호출하는 것과 아무런 관련이 없습니다.

오류는 거의 확실하게 다른 곳에 있습니다. stdout 버퍼링으로 인해 오류의 위치가 혼동 스러울 수 있습니다. 문자열이 stdout으로 인쇄되고 있지만 메모리에 버퍼링되어 문자열이 표시되지 않고 프로그램이 충돌합니다 표시되기 전에 이를 방지하려면 모든 인쇄 문구 뒤에 출력물을 플러시 (예 : std::cout << std::endl 또는 std::cout << std::flush 또는 명시 적으로 std::cout.flush())하거나 std::cout 대신 std::cerr (기본적으로 버퍼링되지 않음)으로 플러시해야합니다.

+0

나는 당신이 제안한 것을 시도했다. 당신의 생각은 합법적 인 것처럼 보입니다. 모든 cout 문을 플러시 할 때 콜백의 문을 실행하지 않고 프로그램이 중단됩니다. 새로운 오류는 _ZNKSt9basic_iosIcSt11char_traitsIcEEcvPvEv, 버전 GLIBCXX_3.4입니다. 나는 그것을 조사하려고 노력할 것이다. 제안은 권장됩니다 :) – kona

+0

U가 링크 오류라고 말했기 때문에 소스를 알아내는 데 꽤 시간이 걸렸습니다. 내 실수는 콜백 함수에 null 포인터를 전달하려고 시도하는 것이 었습니다. – kona

0
#include <iostream> 
using namespace std; 

int calc(int x){ 
    cout<< "calc:" << x << endl; 
} 

int CALC(int x) { 
    cout << "CALC: " << x << endl; 
} 


int foo (int a, int(*callback)(int)){ 
    cout << "Calling calc on:" << a << endl; 
    (*callback)(a); 
} 

int main() { 
    cout << "START" << endl; 

    foo(5, calc); 
    foo(6, CALC); 
} 

잘 작동합니다.

gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00) 

참고 : 나는 당신의 "checkValue (x)는"전화를 제거, 문제가 기호 _ZNSaIcEC1Evstd::allocator<char>::allocator() 제로 인수 생성자의 변환 된 이름입니다