문제

다음 질문의 복제 : C 기능 충돌


안녕하세요, 현재 프로젝트에서는 어떤 종류의 인터페이스 lib를 사용해야합니다. 기능 이름은이 인터페이스에 의해 제공되며,이 기능은 개발자 선택입니다. 내가 말할 수있는 한, 프로젝트는이 기능을 사용해야하며, 컴파일에있어 LIB를 선택하고 기능을 선택해야합니다. 내가하려고하는 것은 기존의 lib와 내 lib를 동시에 다른 사람을 감싸서 mein 함수로 호출하는 것입니다.

Otherlib :

int function1 (int a) {
// do something
}

mylib :

int function1 (int a) {
//my code here
    otherlib::function1(a);
}

문제는 다른 lib에 액세스 할 수없고 다른 lib에는 네임 스페이스가 없다는 것입니다. 나는 이미 시도했다

namespace old {
    #include "otherlib.h"
}

그런 다음 내 함수에서 Old :: Function1로 Old Function을 호출하십시오. 이것은 헤더 파일 만있는 한 작동합니다. LIB는 기호를 전 세계 공간으로 다시 내보내고 있습니다. 또한 같은 것

namespace new {
    function1 (int a) {
        ::function1(a);
    }
}

작동하지 않았습니다. 마지막으로, 나는 ifdefs를 시도하고 제안 된 것을 정의합니다. 여기

그러나 나는 성공하지 못했습니다.

이것을 해결하는 방법이 있습니까? 미리 감사드립니다.

편집 : 나는 오래된 lib에 액세스 할 수 없거나 프로젝트를 모두 사용하지 않습니다.

edit2 : 적어도 오래된 lib는 정적입니다.

도움이 되었습니까?

해결책

C의 네임 스페이스는 라이브러리 이름을 사용하여 해결되었습니다.

libfoo-> foo_function1
libbar-> bar_function1

이 접두사는 실제 네임 스페이스입니다. 그래서 당신이 libbar를 쓰면

int bar_function1(int a) {
     function1(a);
}

이것이 문제를 해결하는 방법입니다.

C 네임 스페이스가 있습니다 --- 방금 접두사라고 불리는 경우;)

또 다른 옵션은 다음과 같은 라이브러리의 동적로드로 다양한 더러운 트릭을 수행하는 것입니다.

h1=dlopen("libfoo.so")
foo_function1=dlsym(h1,"function1")

h2=dlopen("libbar.so")
bar_function1=dlsym(h2,"function1")

다른 팁

마치 다른 LIB가 C이고 코드가 C ++ 인 것처럼 보입니다. 당신은 엉망인 문제를 해결할 수 있습니다 (C ++ 컴파일러는 기호를 맹그합니다. 기호 이름에 추가 물건을 추가하면 과부하 등을 차별화합니다).

라이브러리가 순수한 C 인 경우 시도 할 수 있습니다.

extern "C" { // disable mangling of symbol names in the block
#include "otherlib.h"
}

namespace new_lib { // new is a reserved word
   int function1( int a ) {
      ::function1(a);
   }
}

나는 그것을 시도하지 않았다. 또한 오류 메시지를 제공하는 것을 고려하십시오.

또 다른 옵션은 (라이브러리가 동적 인 경우) LIB를 동적으로로드하고 함수를 호출하는 것입니다. Linux (Windows에 대해 잘 모르겠습니다)에서 Dlopen을 사용하여 라이브러리를 열고 DLSYM을 열어 기호를 얻고 다음을 호출 할 수 있습니다.

// off the top of my head, not tried:
int function1( int a )
{
   int (*f)(int); // define the function pointer
   void * handle = dlopen( "library.so" );
   f = dlsym( handle, "function1" );
   f( a ); // calls function1(a) in the dynamic library
}

이 경우 라이브러리와 연결되지 않으므로 기호 충돌을 얻지 못하지만 다시 동적 라이브러리에만 유효하며 정기적으로 사용하기에 매우 번거 롭습니다.

업데이트

사용자가 'OtherLib'을 직접 사용하지 않고 (헤더가 포함되지 않음) C ++ 만 사용하면 첫 번째 접근 방식이 가능할 수 있습니다 (읽기가 끔찍한 경우에도).

// newlib.h
namespace hideout {
   int f( int a );
}
using namespace hideout; // usually I would not put this on the header

// newlib.cpp
extern "C" { // if otherlib is C, else remove this line
#include "otherlib.h"
}
namespace hideout {
   int f( int a ) { return ::f( a*2 ); }
}

// main.cpp
#include "newlib.h"
int main()
{
   std::cout << f( 5 ) << std::endl;
}

어떻게 작동합니까? 사용자 코드는 포함하지 않으므로 function1 (예제 f ()) 만 표시됩니다 Otherlib.h. 컴파일 장치 내부에는 두 개의 선언이 표시되지만 네임 스페이스 사용을 통해 차별화됩니다. 헤더의 사용 명령문은 CPP에서 완전히 자격을 갖추고 있기 때문에 귀찮게하지 않습니다. 사용자 main.cpp 헤더 만 포함하므로 컴파일러는 은신처 :: f, 사용 명령문으로 인해 어디서나 볼 수 있습니다. C ++ 기호가 실제 네임 스페이스를 식별하여 엉망이되므로 링커는 아무런 문제가 없습니다.

// g++ 4.0 in macosx:
00002dbe T __ZN7hideout9function1Ei // namespace hideout, function1 takes int, returns int
00002db0 T _function1

사용자 코드에 헤더가 모두 포함 된 경우 Otherlib.h 그런 다음 호출하려는 기능을 자격을 갖추어야합니다.

필사적이라면 네임 스페이스 나 접두사를 사용하거나 DLSYM 트릭을 허용하는 래퍼 라이브러리를 작성할 수 있습니다. 이 래퍼 라이브러리는 기호 충돌을 피하기 위해 동적으로 연결되어야합니다. 동적 라이브러리에는 이전 정적 라이브러리가 안전하게 내장되어있을 수 있습니다. 동적 래퍼 라이브러리를 만들 때 정적 라이브러리에서 기호를 내보내지 않도록하십시오.

링크 시간 에이 문제를 해결할 수 없으므로 동적 라이브러리를 통해 런타임에 해당하는 것을 해결해야합니다. 이러한 기능의 상징은 라이브러리가 생성되면 본질적으로 구워집니다. 두 라이브러리가 동일한 기호를 내보내면 정적으로 연결할 수 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top