2014-08-29 1 views
1

이것은 정말 기본적인 질문이며 온라인에서 많은 개념적 답변을 찾았지만 실제로 작동하지는 못했습니다.g ++에서 다른 파일에 정의 된 함수를 사용하는 방법은 무엇입니까?

파일 source.cc

#include <iostream> 

int myfunc() { 
    return 42; 
} 

int main() { 
    return 0; 
} 

을하고 내가 통해 오브젝트 파일 source.o 작성 : 여기

내가 무엇을 가지고 마지막으로

g++ -c source.cc 

을, 나는

를 사용
ar rvs source.a source.o 

source.a 정적 라이브러리.

이제 문제가 생깁니다.

파일 user.cc은 다음과 같습니다

내가 분명히 라이브러리에 정의 된 함수를 사용하기를 원하지만
#include <iostream> 
#include <source.a> 

int main() { 
    std::cout << myfunc(); 
} 

user.cc 컴파일 할 때 :

g++ user.cc -o user 

을 내가받을 오류 :

user.cc:2:22: fatal error: source.a: No such file or directory 
compilation terminated. 
+0

꺾쇠 괄호는 일반적으로 현재 디렉토리를 검색하지 않지만, 그 점 옆에 있습니다. 나는 당신이 .a 파일을 포함하기를 매우 의심한다. 그것에 링크하십시오. – chris

+0

당신은 도서관을 포함시키지 않으며 * 도서관에 * 링크하십시오 *. 함수 선언 (일반적으로 헤더 파일에 위치)이 필요합니다. '메인 '을 정의하는 라이브러리를 링크 할 때 문제가 발생할 수도 있습니다. – crashmstr

답변

1

제대로 명령 줄에서 g ++ 사용하기 코드 조직에 대한 다음주의 사항을 고려하는 것이 좋습니다. 당신의 라이브러리 코드에서

, 당신은은 main() 함수를 정의 한다. main()의 정의는 라이브러리 (예 : user.cc)를 사용하는 코드의 일부 여야합니다.

또한, 당신은 그들이 선언 라이브러리 내 보낸 함수의을 가져 오는 데 사용할 수있는 라이브러리 헤더 파일의 클라이언트에 배포 할 수 있습니다.그래서

,이 같은 일부 파일을 정의 고려 :

헤더 파일 :

// library.h -- Public header for your library's clients 

#pragma once // or use #ifndef/#define/#endif "header guards" 

// Functions exported by your library: 
// their *declarations* go in the library's public header file; 
// their *definitions* go in the library's implementation file(s) (.cc, .cpp) 
// (exception: inline functions/methods, that are implemented in headers). 

int myfunc(); 

// Add some other exported functions... 

// NOTE: "extern" not needed in C++! 

실행 파일 : 다음

// library.cc -- Library implementation code 
#include "library.h" // library public header 
#include <...>  // headers required by this implementation code 

// *Define* functions exported by the library 

int myfunc() { 
    return 42; 
} 

// ...other function implementations... 

, 라이브러리의 클라이언트가 다만 것입니다 :

(210)는

파일 main()를 포함하여 라이브러리를 사용 :

// main.cc (or user.cc or whatever you call it) 

#include <iostream> // For std::cout, std::endl 
...#include any other required header file... 

#include "library.h" // Your library public header file 

int main() { 
    // Call library's function 
    std::cout << myfunc() << std::endl; 
}  

// NOTE: main() is special: "return 0;" can be omitted. 
+0

정말 고마워요. 제게 많은 도움이되었습니다. 이제 header.h와 source.cc 헤더가 생겼으므로 main.cc를 main.cc로 컴파일했습니다. 그래도 라이브러리를 링크해야합니까? –

+0

@mihapriimek : 도움이 된 것을 기쁘게 생각합니다. BTW : 좋은 Stackoverflow 시민으로서 도움이되는 모든 답변을 upvote하고 (이 스레드에 여러 가지가 있음) 답변을 가장 잘 표시 할 수 있습니다. –

+0

물론, 나는 사람들이 제안한 모든 다른 것들을 시도함으로써 어느 것이 가장 큰 도움이되었는지 알아 내려고 애 썼습니다. (특정 답변을 upvoting하기 전) –

1

#include 라이브러리 아카이브가 없습니다. 그것은 소스 코드를 포함하지 않습니다. 그것은 객체 코드를 포함합니다. 링커의 명령 행에 넣으십시오.

g++ -c user.cc으로 컴파일하십시오. g++ -o user user.o source.a로 링크하십시오.

0

기본적으로 #include <...> 구문 (꺾쇠 괄호 포함)은 시스템 파일을 검색하여 지정된 파일을 찾습니다. 다른 디렉토리를 검색하려면 -L 옵션을 사용할 수 있으며 라이브러리와 연결하려면 명령 행에서 source.a을 사용해야합니다. 이처럼 :

g++ user.cc -L/path/to/library source.a -o user 
3

#include 사용자가 지정한 (togehter 모두 컴파일 링커를 사용하는 것보다이

extern int myfunc(); 

예를 들어 시간을 컴파일하고 (라이브러리되지 않음) C/C++ 헤더이어야합니다 모든 명령 줄에서 필요한 파일)

+1

'extern'을 제거하면 중복 됨 –

+0

하지만 변수가 필요하기 때문에 좋은 연습이라고 생각합니다. 그것을 가지고있는 것이 나쁘지 않고 필요한 곳과 그렇지 않은 곳을 생각할 필요가 없습니다. – firda

+0

@firda : 솔직히, extern을 사용하여 전역 변수를 내보내는 것은별로 좋지 않은 것 같습니다. 어떤 형태의 전역 상태를 공유해야하는 경우 getter/setter ** 함수를 내보낼 수 있습니다. *. C++에서 export 함수에 대한 extern이 중복되고, 제거되어야한다고 나는 동의한다. 나는 foo (void)를 싫어하고 C++에서 더 간단하게 foo()를 선호한다. –

2

C++ (및 C99)에서는 이전에 호출 한 모든 함수를 미리 선언해야합니다. 이렇게하려면 정의없이 함수의 "서명"을 제공하십시오. 귀하의 경우,이 myfunc이 인수를 사용하지 않습니다와 int을 반환하는 함수입니다 컴파일러를 알려주는 문

int myfunc(); 

을 할 것이다. 일반적으로이 함수 선언은 헤더에 포함됩니다.

.a 파일은 C 또는 C++ 코드가 포함되어 있지 않은 컴파일 된 아카이브이므로 #include - C++ 파일에 저장하면 작동하지 않습니다.대신 C 또는 C++ 헤더를 만들고 최종 실행 파일에 링크 할 파일 목록에 .a 아카이브를 추가해야합니다. g ++의 경우 이것은 매우 쉽습니다. 예를 들어

g++ user.cc source.a -o executable 

을 예로들 수 있습니다.

0

아이디어의 커플 (토론 1) 당신은 라인을

INT의 myfunc에 포함되어 source.h라는 헤더 파일을 작성해야합니다에 추가 할) 또는 extern int myfunc(); 상단에 user.cc에서

2)이 함수가 정의 된 컴파일러를 알려주는 포함 라인 "source.h" 해야

3) 나는 당신이 밖으로 주요 기능을해야한다고 생각 source.cc 또는 최소한 정적으로 만드십시오.

다른 사람들이 지적했듯이, 라이브러리 파일 (source.a)을 포함 할 수 없습니다. 컴파일 및 링크 프로세스가 그대로 작동해야합니다.

관련 문제