2014-03-06 2 views
1

내부 프로젝트 용 차세대 프레임 워크 아키텍처를 설계하고 있습니다. 본질적으로 즉시로드/언로드 할 수있는 응용 프로그램에 API를 제공하는 런타임 시스템이 있습니다.일반적인 API 게시 기법

프레임 워크에는 맞춤 "기기"라이브러리가 있습니다. 이러한 기기의 현재 인터페이스는 매우 일반적입니다. posix로드/언로드/읽기/쓰기/등 생각 ... 프레임 워크의 중요한 원칙 중 하나는 애플 리케이션 장치의 특성에 대해 거의 알 필요가있다.

이 인터페이스는 응용 프로그램 개발자가 응용 프로그램 자체에서 공통 기능을 다시 작성하는 위치로 분류됩니다.

나는 이런 식으로 프레임 워크 API를 디자인하는 것에 대한 제안을 읽을 곳을 찾고있다. 프레임 워크의 "장치"작성자가 인터페이스를 게시하는 데 사용할 수있는 유용한 도구 집합은 무엇입니까? 가장 좋은 방법은 무엇입니까 ~ 인터페이스를 게시 하시겠습니까?

+0

현재 시스템에서 부족한 부분에 대해 구체적으로 설명하여 응용 프로그램 개발자가이를 포기하도록 유도 할 수 있습니까? 어떤 종류의 API 함수를 추가해야할까요? 이미로드/언로드/읽기/쓰기가 추가 된 경우 어떤 문제가 발생합니까? –

+0

현재 시스템이 너무 일반적입니다. 신호 처리를하는 장치 하나와 모터 컨트롤러 인 장치 하나를 만들 수 있습니다. 게시에 사용할 수있는 유일한 인터페이스 메소드는로드/언로드/읽기/쓰기 등입니다. 장치 작성자가 해당 장치에 대한 고유 한 사용자 정의 메서드/함수를 게시 할 수 있지만 앱이 반드시 필요하지는 않도록하고 싶습니다. 여분의 것을 # 포함해야합니다. 이들은 설치된 장치의 프레임 워크를 쿼리 한 다음 장치 작성자가 게시 한 인터페이스를 가져올 수 있어야합니다. – Lother

+0

그래서 앱에 추가 기능이 없으며 추가 기능을 호출 할 수 있는지, 잠재적으로 추가 기능을 호출 할 수 있는지, 어떻게 호출 할 것인지/결정할 때 * 결과를 어떻게 처리 할 것인지 결정할 수 있습니까? 변경되지 않은 App이 해당 함수에 대한 호출을 지정하는 어딘가의 입력 (예 : 설정 파일, 키보드 또는 UI 위젯)을 읽거나 App을 편집하여 호출을 지정하겠습니까? –

답변

2

제안 -은 제안한 내용과 크게 다를 수 있지만 의견은 유용하다고 생각합니다.

동기식 "호출"의 경우 앱 모듈이 필요한 드라이버 기능 및 많은 인수의 표시를 보내도록하려면 결과를 검색하십시오. 이는 함수 및 값의 인코딩이 전송되는 두 번째 별개의 읽기/쓰기 스트림을 사용함으로써 일반적인 방식으로 수행 할 수 있습니다. 그래서, 드라이버 API가 포함 말 :

string get_stuff(string x, int y, double d[]); 

이 코드가 아닙니다 - 그것은 프레임 워크/응용 프로그램은/구문 분석을 인쇄하고 잠재적으로 데이터가 전송되고 상응 소비 확인하는 데 사용할 수있는 텍스트입니다.

그러면 app 모듈은 함수 식별자와 입력 스트림으로 드라이버에 "호출"을 쓴 다음 결과를 읽습니다 (app 매개 변수에 원하는 매개 변수 값이있는 동일한 이름의 변수가 있다고 가정).

driver_api << "get_stuff " << escape(x) << ' ' << y << " [" << d.size() << "] "; 
for (auto i = d.begin(); i != d.end(); ++i) 
    driver_api << ' ' << *i; 
driver_api << '\n'; 

std::getline(driver_api, result); 

그것의 좀 더 많은 작업 (시간 반?) driver_api 포장 위의 공백이나 다른 분리/구분 기호를 삽입, 용기의 스트리밍을 지원, 및/또는 데이터를 전송할 수있는 사용자 정의 스트림 랩퍼를 작성하기 또한 응용 프로그램 모듈이 호출에 대해 위의 포장 정상적인 C++ 기능을 쓸 수

(driver_api << "get_stuff" << x << y << d) >> result; 

: 바이너리 형태로, 당신이 청소기 및/또는 같은 위, 뭔가의 빠른 가치 지향 버전을 쓰기시키는 :

string get_stuff(const std::string& x, int y, const std::vector<double>& d) 
{ 
    string result; 
    (driver_api_ << "get_stuff" << x << y << d) >> result; 
    return result; 
} 

드라이버 측에서 일치하는 비 직렬화 루틴을 작성하여 스트림에서 지정된 app 모듈 값을 복구합니다.

특정 아키텍처의 경우 디버그 정보 또는 ABI 지식 등을 사용하여 함수를보다 편리하게 호출 할 수있는 라이브러리를 얻을 수 있습니다. 반면 위의 코드는 표준 C++ 만 필요하며 휴대 가능하도록 작성할 수 있습니다 (엔디안 값의 바이너리 직렬화 수행).

EDIT - 바이너리 직렬화의 예 (출력은 현재/실행 중이지만 유효성에 대해서는 신중하게 검사되지 않음/대부분 고정 폭이지만 문자열은 NUL으로 끝나며 크기가 접두어로되어있는 컨테이너는 다음 필드 유형 정보를 보내지 않음) 매우 쉬운 버전을 만들 수 있습니다.) :

#include <iostream> 
#include <vector> 

#include <winsock2.h> 
typedef signed char int8_t; 
typedef signed short int16_t; 
typedef signed int32_t; 
typedef unsigned char uint8_t; 
typedef unsigned short uint16_t; 
typedef unsigned uint32_t; 

class Binary_IOStream 
{ 
    public: 
    Binary_IOStream(std::istream& i, std::ostream& s) : i_(i), s_(s) { } 
    typedef Binary_IOStream This; 
    This& operator<<(int8_t x) { return write(x); } 
    This& operator<<(int16_t x) { return write(htons(x)); } 
    This& operator<<(int32_t x) { return write(htonl(x)); } 
    This& operator<<(uint8_t x) { return write(x); } 
    This& operator<<(uint16_t x) { return write(htons(x)); } 
    This& operator<<(uint32_t x) { return write(htonl(x)); } 
    This& operator<<(const std::string& s) 
     { s_.write(s.c_str(), s.size() + 1); // include NUL, but could size-prefix 
      return *this; } 
    This& operator<<(double x) { return write(x); } 

    template <typename T> 
    This& operator<<(const std::vector<T>& v) 
     { return write_range(v.begin(), v.end()); } 

    template <typename Iterator> 
    This& write_range(Iterator begin, Iterator end) 
    { 
     operator<<(std::distance(begin, end)); 
     while (begin != end) 
      operator<<(*begin++); 
     return *this; 
    } 

    private: 
    template <typename T> 
    This& write(const T& t) 
     { s_.write((const char*)&t, sizeof t); return *this; } 

    std::istream& i_; 
    std::ostream& s_; 
}; 

int main() 
{ 
    Binary_IOStream bs(std::cin, std::cout); 

    bs << ('A' << 24) + ('b' << 16) + ('c' << 8) + 'D'; 
    bs << "hello world!"; 
    std::vector<double> v; 
    v.push_back(3.14); 
    v.push_back(2.72); 
    bs << v; 
} 
+0

이것은 제가 생각했던 정확하게 같은 생각입니다. 호출을 스트림으로 인코딩하는 표준 방법을 제안 할 수 있습니까? 뭔가 빠른 네이티브 형식으로하지만 원시 데이터를 선호하는 C/C + + 라이브러리를 잡을 수 있습니다 (XML 래퍼 잔뜩 싶지 않아) 빠른입니다. – Lother

+0

나는 하나를 알지 못하지만 어떻게 할 수 있는지 설명하는 약간의 코드로 편집 할 것입니다. –

+0

나는 귀하의 제안을 완전히 이해한다고 생각합니다. 나는 지금 당장 무언가를 코딩 할 수 있습니다. 문제 없습니다. 이것을하기위한 표준 방법이 있다면 좋을 것입니다. 나는 거의 없다고 믿을 수 없다. 내 검색의 다음 단계라고 생각합니다. JSON은 이와 비슷한 일을하지만 JSON은 충분히 빠르지 않다는 것을 알고있다. (ASCII 문자열 데이터를 인코딩한다.) 가능한 한 스트림에 넣지 않고 인코딩 된 데이터가 이미 네이티브에 있기 때문에 스트림을 매우 빨리/분해하는 것을 원한다. 체재. – Lother