Linux C ++ 오류 : 'dlopen'에 대한 정의되지 않은 참조


147

Linux에서 C ++ (Eclipse)로 작업하고 라이브러리를 사용하고 싶습니다. 이클립스는 나에게 오류를 보여줍니다 :

undefined reference to 'dlopen' 

당신은 해결책을 알고 있습니까?

내 코드는 다음과 같습니다.

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char **argv) {
    void *handle;
    double (*desk)(char*);
    char *error;

    handle = dlopen ("/lib/CEDD_LIB.so.6", RTLD_LAZY);
    if (!handle) {
        fputs (dlerror(), stderr);
        exit(1);
    }

    desk= dlsym(handle, "Apply");

    if ((error = dlerror()) != NULL)  {
        fputs(error, stderr);
        exit(1);
    }

    dlclose(handle);
}

답변:


254

libdl과 연결하고 추가해야합니다.

-ldl

링커 옵션


2
같은 문제가 발생했습니다 ... 링커 플래그 텍스트 필드의 Project> Properties> C / C ++ Build> Settings> (My Linker)> Miscellaneous 아래에 컴파일러 플래그를 추가했습니다. 아무것도하지 않았다.
MirroredFate

3
하가, 좋아,이 문제를 가지고 다른 사람을 위해, 라이브러리가 아닌 기타로 이동을 제외하고, 위의 경로를 사용하고 'DL'추가
MirroredFate

2
이 답변이 도움이되었습니다. libdl.so의 위치를 ​​찾으려면 루트 디렉토리로 이동하여 다음을 입력하십시오.locate libdl.so
Nav

MirroredFate의 답변도 저에게 효과적이었습니다. 나는 왜 그런지 이해하지 못한다. 내가 연결해야했던 다른 모든 라이브러리는 기타에 배치되었을 때 작동했습니다.
집합

75

@Masci는 정확하지만 C (및 gcc컴파일러)를 사용하는 경우 작동하지 않는다는 점을 고려하십시오.

gcc -ldl dlopentest.c

그러나 이것은 :

gcc dlopentest.c -ldl

알아낼 조금 나왔어 ...


2
옵션의 순서도 중요하다는 것을 알았습니다. sqlite3을 사용하는 프로젝트에서 -lsqlite3 뒤에 -ldl (및 -lpthread)을 넣어야합니다. 그것이 무엇인지 모릅니다. RTFM 만 있으면 대답이 확실합니다.

이런 쓰레기 야! 나는 옵션을 먼저 두는 것이 더 나을 것이라고 생각하지 않았을 것입니다. @knocte 감사합니다!
Joe Strout

@ user2918461 머리에 못을 박았다. 나는 -l을 "올바른"순서로 넣어야했다.
NDEthos


8

주제는 꽤 오래되었지만 cegui 0.7.1 (openVibe 전제 조건)을 컴파일하는 동안 오늘 같은 문제로 어려움을 겪었습니다.

나를 위해 일한 LDFLAGS="-Wl,--no-as-needed" 것은 Makefile에서 설정하는 것이 었습니다 .

나는 또한 시도했다 -ldl위해 LDFLAGS하지만 아무 소용.


8

이것은 작동하지 않습니다 :

gcc -ldl dlopentest.c

그러나 이것은 :

gcc dlopentest.c -ldl

그것은 확실히 성가신 "기능"입니다

heredoc 구문을 작성할 때 어려움을 겪고 흥미로운 사실을 발견했습니다 . 를 사용하면 다음 CC=Clang과 같이 작동합니다.

$CC -ldl -x c -o app.exe - << EOF
#include <dlfcn.h>
#include <stdio.h>
int main(void)
{
  if(dlopen("libc.so.6", RTLD_LAZY | RTLD_GLOBAL))
    printf("libc.so.6 loading succeeded\n");
  else
    printf("libc.so.6 loading failed\n");
  return 0;
}
EOF

./app.exe

뿐만 아니라 이들 모두 :

  • $CC -ldl -x c -o app.exe - << EOF
  • $CC -x c -ldl -o app.exe - << EOF
  • $CC -x c -o app.exe -ldl - << EOF
  • $CC -x c -o app.exe - -ldl << EOF

그러나와 CC=gcc마지막 변형 작업; -ldl이후 -(stdin 인수 기호)


5

당신은 이것을 추가하려고 할 수 있습니다

LIBS=-ldl CFLAGS=-fno-strict-aliasing

구성 옵션


1
LIBS 변수를 사용하면 명령 줄의 올바른 위치에 -ldl을 배치하도록 구성 할 수있었습니다.
던컨

5

CMake를 사용하여 프로젝트를 컴파일하고 있었고 동일한 문제를 발견했습니다.

여기에 설명 된 솔루션은 매력처럼 작동합니다. 단순히 target_link_libraries () 호출에 $ {CMAKE_DL_LIBS}를 추가하십시오.


1
감사! 이것은 나에게도 도움이되었습니다. 그러나 컴파일러를 clang으로 변경 한 후에 만 ​​가능 SET(CMAKE_CXX_COMPILER /usr/bin/clang++)합니다. 는 / usr / 빈과 함께 / C ++에 내 우분투는 (또한 발칸 까마귀의 답변을 참조) 작동하지 않는
thomasfermi

3

makefile을 위해 다음과 같은 작업을 수행해야했습니다.

LDFLAGS='-ldl'
make install

링커 플래그를 make에서 linker로 전달합니다. 메이크 파일이 자동 생성 된 것은 중요하지 않습니다.



1

dl 함수를 사용하려면 링커에 -ldl 플래그를 사용해야합니다.

어떻게 일식에서 그것을합니까?

를 눌러 프로젝트 -> 속성 -> C / C ++ 빌드 -> 설정 -> GCC C ++ 링커 ->
도서관 ->은 "도서관 (-l)"상자에 눌러 "+"기호 -> 쓰기 " DL (따옴표없이)는"->를 눌러 확인 -> & 깨끗한 재건 프로젝트를.


1
 $gcc -o program program.c -l <library_to_resolve_program.c's_unresolved_symbols>

-l dl의 배치가 중요한 이유에 대한 좋은 설명

그러나 문서에는 꽤 간결한 설명이 있습니다 From From $ man gcc

   -llibrary
   -l library
       Search the library named library when linking.  (The second
       alternative with the library as a separate argument is only for POSIX
       compliance and is not recommended.)
       It makes a difference where in the command you write this option; the
       linker searches and processes libraries and object files in the order
       they are specified.  Thus, foo.o -lz bar.o searches library z after
       file foo.o but before bar.o.  If bar.o refers to functions in z,
       those functions may not be loaded.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.