2010-03-28 4 views
1

궁금 해요 :액세스 C++ 기능이

이의 내가 SQL에 저장된 데이터의 무리가 있다고 가정 해 봅시다, funcname에 호출 할 수있는 필드 중 하나, 기능을 말할 수 이름은 "myFunction"과 유사한 데이터를 포함 할 것입니다. 내가 궁금해하는 점은 함수 이름을 추출하고 실제로이 함수를 호출하는 것보다 더 좋은 방법이 있습니까?

funcName을 funcId로 변경하고 배열이나 이와 유사한 것으로 연결하는 방법을 생각해 볼 수 있지만 데이터를 추가 할 수있는 좀 더 동적 인 것이 필요합니다. 즉, 새로운 함수에 대한 호출을 추가 할 때마다 실제 소스 코드를 업데이트 할 필요없이 함수가 이미 존재하고 우리가 호출 한 범위 위치를 통해 액세스 할 수 있다고 가정합니다.

도움을 주시면 감사하겠습니다.

답변

3

자동으로 등록되는 새 기능을 정의하려면 매크로를 사용하십시오.

// callable_function.h 
class CallableFunction { 
public: 
    virtual void operator()() = 0; 
}; 

class CallableFunctionRegistry { 
public: 
    static CallableFunction *Register(const string &func_name, 
            CallableFunction *func_impl) { 
    Instance()->registered_functions_.insert(make_pair(func_name, func_impl)); 
    } 

    static void Run(const string &func_name) { 
    (*Instance()->registered_functions_[func_name])(); 
    } 

private: 
    static CallableFunctionRegistry *Instance() { 
    static CallableFunctionRegistry *instance = new CallablefunctionRegistry; 
    return instance; 
    } 

    CallableFunctionRegistry() {} 
    map<string, CallableFunction*> registered_functions_; 
}; 

#define REGISTER_CALLABLE_FUNCTION(FuncName) \ 
    class FuncName : public CallableFunction { \ 
    public: \ 
    virtual void operator()(); \ 
    }; \ 
    CallableFunction *impl_ ##FuncName = \ 
    CallableFunctionRegistry::Register(#FuncName, new FuncName); \ 
    void FuncName::operator()() 

그리고 그것을 사용과 같은 :

//other_file.cc 
REGISTER_CALLABLE_FUNCTION(DoStuff) { 
    // do stuff here. 
} 

을 그리고이 :

//yet_another_file.cc 
CallableFunctionRegistry::Run("DoStuff"); 

당신은 기능을 할 수있는 대신 CallableFunction 객체의 ptrs,하지만 내 구문은 불투명하다. 어느 쪽이든, 중복 등록에 대한 오류 검사를 추가하고 조회를 찾을 수 없습니다.

+0

와우, 내가이 코드를 정확히 사용하지 않았을지라도 나는 나를 나중에 다른 목표로 이끄는 또 다른 길로 인도했다. 답장과 정보에 대해 대단히 감사합니다. – Undawned

+0

행운을 빌어서 도울 수있어서 기쁩니다. – Stephen

1

당신은 당신이 SQL에서 recevied 텍스트를 사용하고 이것은 당신이 (당신이 Windows를 사용하는 가정) 호출 할 수있는 함수 포인터를 줄 것이다 GetProcAddress()

호출 할 수 있습니다.

리눅스를 들어, 다음, 프로그램 시작시 포인터 또는 펑터 기능지도 조회를 통해 이름으로 전화를 dlsym

+0

내가 틀렸다면 정정하십시오.하지만 GetProcAddress()는 DLL의 내 보낸 함수/변수를 참조합니다. 현재 프로그램은 DLL에 아무 것도 내보내지지 않습니다. – Undawned

+0

@Undawned 그런 다음 사용하려는 모든 기능을 내보내는 dll을 만들어야합니다. – SigTerm

+0

DLL이 필요없는 .EXE에서 함수를 내보낼 수도 있습니다. –

2

설정에서 이름의 매핑을 살펴. 확장을 위해 동적 라이브러리를 사용할 수도 있습니다.

컴파일러/인터프리터에서는이라고 불리며 대개 유형 (클래스/구조체), 데이터 선언 (변수) 및 함수 설명자 (인수 및 반환 형식 등)도 포함합니다. 또한 중첩 될 수 있습니다 범위에.

1

접근 방식 # 1 (가장 복잡함) :
응용 프로그램에이 플러그인을 알리는 몇 가지 공용 함수가있는 동적으로 링크 된 여러 라이브러리 (* .dll on linux, * .so on linux)로 구성된 플러그인 시스템을 개발하십시오. 지원, 함수 이름 및 포인터. 시작시 플러그인을 검색하여 함수 이름을 포인터로 매핑 할 함수 목록을 작성하십시오.

가변 개수의 매개 변수에 대한 문제가 예상됩니다.

Approach # 2 (무차별 대입) : 하나의 동적 링크 라이브러리 내에서 호출 할 수 있어야하는 모든 함수를 저장하십시오. 함수 이름을 데이터베이스에서 추출 할 때 Linux에서 GetProcAddress (win32) 또는 dlsym (?)을 사용하여 함수 포인터를 가져옵니다.

가변 개수의 매개 변수에 대한 문제가 예상됩니다. 가장 빠르고 똑똑한 방법은 아닙니다.

접근 방식 # 3 (가장 유연함) : 앱에 루아 또는 파이썬 인터프리터를 내장하십시오.
이 방법을 사용하면 데이터베이스 내의 전체 기능을 저장할 수 있으며 그 중 하나를 호출 할 때 문제가 없어야합니다. 당신은 여전히 ​​당신이 접근 할 수있는 기능의 목록을 선언해야합니다.

그러나 이것은 충분히 어리석은 증거는 아니지만 충분히 조심하지 않으면 데이터베이스 내에서 전체 앱을 망칠 수 있습니다.

+0

좋은 답변입니다. 불행히도 제안 된 방법은 전체 프로젝트 자체에 대해 너무 많은 조사를 필요로하지만 제가 작업하는 것은 기본 코드에서의 그러한 대규모 점검을 정당화하지 않는 프로젝트의 작은 부분입니다. 정보를 주셔서 감사합니다 =). – Undawned

관련 문제