2011-08-15 4 views
0

다른 C++ 파일이 많습니다 (아마도 수백 개). 각 함수는 10 개의 함수를 포함하는데, 모두 함수가 int와 double을 받아 int를 반환합니다.특정 파일의 함수 포인터 얻기

int (*foo)(int, double); 

을 그리고 나는이 함수 포인터 (10)를 포함하는 클래스를 가지고 :

그래서 이러한 파일 중 하나에서 이러한 기능 중 하나에 대한 포인터는 다음과 같이한다.

이 클래스의 생성자를 이러한 C++ 파일 중 하나의 파일 이름으로 가져 와서 해당 파일의 함수를 포인터에 넣고 나중에 함수를 사용할 수 있습니까?

서로 다른 파일의 두 함수가 같은 이름을 갖고 있어도 작동한다는 것이 좋습니다 (여러 프로그래머가 서로 다른 파일을 목록에 제출할 수 있으며 해당 파일에 동일한 이름을 사용할 수 있음). 함수), 그러나 그것이 가능하지 않다면 나는 그것을 피할 수있는 것을 찾아 낼 수 있습니다.

필자가 검색 한 내용에서 기능을 선택할 때 파일을 구분할 수있는 항목을 찾을 수없는 것 같습니다. 함수를 하나의 파일로 연결한다고해도 지정하려고하는 문제가 있습니다. 10 가지 함수가 선택됩니다 (모두 동일한 인수를 가짐).

이렇게 할 방법이 있습니까? 내가 생각지 못했던 더 나은 해결책이 있습니까?

+0

기능은 네임 스페이스 파일 하나에 함께 넣을 수 있습니다. 그런 다음 템플릿을 사용하여 지정된 네임 스페이스를 사용하여 각각의 객체를 만들 수 있습니다. 예제를 추가하면 더 자세하게 설명하려고합니다. – zabulus

답변

1

어떤 방법이 있습니까? 내가 더 나은 솔루션이 있습니까 그냥 생각하지?

제 생각에는 다른 네임 스페이스를 사용할 수 있습니까? 나는 각각의 네임 스페이스에있는 10 개의 함수 그룹을 의미한다. 그런 식으로 그들은 더 이상 충돌하지 않을 것입니다.

외에도 일부 dlsym + dlopen의 이상 함 (또는 해당 win32 사본)을 시도해 볼 수 있습니다. 그것은 내가 할 수있는 일이 아닙니다.

0

나는 dynamic linking library (리눅스 땅에서는 shared object)이라고 설명합니다.

+0

코드가 실제로 플러그인 아키텍처를 구걸하는 것처럼 들립니다. 모든 함수를 동일하게 호출하고 각 파일을 자체 .so/.dll로 컴파일하고 런타임에 * 1 * 동적 라이브러리를로드하고 이름으로 함수 포인터를 가져옵니다. – Torp

0

당신이 글자 그대로 무엇을 얻을 수있게하려면 각 C++ 파일을 동적 라이브러리로 변환하고 라이브러리 생성자에서 FILE 문자열을 키로 사용하여 일부 글로벌 맵에 함수 집합을 등록하거나 정적으로 선언하고 make 각 파일에는 이니셜 라이저가 동일한 전역 맵에서 함수의 등록을 트리거하는 정적 변수가 있습니다.

플러그인 방식을 사용하여 구현하려면 here과 비슷한 방식으로 수행 할 수 있습니다 (다운로드는 plugin.tgz, 기사는 아직 준비되지 않음). 내용 :

  • app.cc - 응용 프로그램, 부하 모든 플러그인 '라이브러리
  • module.cc - 비즈니스 인터페이스 module_ifc.h를 구현하는 플러그인 클래스와 "로드 할 수있는"인터페이스 bootstrap_ifc.h
  • client.cc - bootstrap_ifc.h를 구현하고 메서드를 모듈에서 사용한 플러그인입니다.cc 런타임에 해결됨

동일한 기능 세트를 가진 각 C++ 파일에는 추상 비즈니스 인터페이스 (유용한 부분, 모든 기능) 및 부트 스트랩 인터페이스 (통합 초기화 부분, 플러그인에 의해 사용됨)를 구현하는 클래스가 있습니다 짐을 싣는 사람). 이러한 각 클래스는 클래스 인스턴스 생성자 및 소멸자 메서드를 선언하는 별도의 공유 라이브러리에 저장됩니다.

간단한 클래스는 리눅스 공유 라이브러리로 작업하기 : 다른 파일에서

#include <dlfcn.h> 

class library { 
    void* _handle; 
public: 
    library(char const* path); 
    ~library(); 

    template <typename F> F func(char const* name); 
}; 

library::library(char const* path) { 
    _handle = dlopen(path, RTLD_NOW); 
    if (!_handle) throw std::runtime_error(dlerror()); 
    std::clog << "opened library " << path << ", handle=" << std::hex << _handle << std::dec << "\n"; 
} 

library::~library() { 
    if (_handle) dlclose(_handle); 
    std::clog << "closed library, handle=" << std::hex << _handle << std::dec << "\n"; 
} 

template <typename F> F library::func(char const* name) { 
    dlerror(); 
    F func = reinterpret_cast<F>(dlsym(_handle, name)); 
    const char *dlsym_error = dlerror(); 
    if (dlsym_error) throw std::runtime_error(dlsym_error); 
    std::clog << "loaded symbol " << name << ", ptr=" << std::hex << ((void*)func) << std::dec << "\n"; 
    return func; 
}