2013-04-13 2 views
1

이의 va_list로 동적 길이 인수 목록을 얻기 위해 C의 방법이있다 (의 va_list) 런타임에 호출 C에서 매우 간단하지만, 대부분의 시간은 ++ 필요하지 http://www.cprogramming.com/tutorial/c/lesson17.html동적 기능은 여기에 설명 된대로

. 현재 Zend 기능을 캡슐화하기위한 최상위 래퍼 클래스를 작성 중입니다.

어쨌든, 동적 함수 을 호출해야합니다. 정상 함수에서 동적으로 printf를 호출합니다.

void ZendParams::setRequired(int &Var ) 
{ 
     // save every var pointer to a stack 
     // and save the type with it. (if needed, does not seems to be) 
     // after call to ZendParams::fetch() 
     // the values are stored in the passed variables 
     this->_params.push_back((void*) &Var); 
     this->_paramStr.append('i'); 
} 

size_t ZendParams::fetch() 
{ 
     if (zend_parse_parameters(
       ZEND_NUM_ARGS() TSRMLS_CC, , 
       this->_paramStr.c_str(), 
       ... 
       ) !== FAILURE) 
     { 

     } 

     return 0; 
} 

그래서 내가 동적으로 zend_parse_parameters에 대한 호출을 만들고 싶어 :

나는 여기에 내가 아마도 이것이 내 생각이 조금 더 나은 설명, 그래서 전쟁을 가지고 원하든이다, 위에서 설명한 예제의 반대 방법을 의미한다.

기본적인 아이디어는 목록에서 vars에 대한 포인터를 추가하고 zend 함수 (참조)에 동적으로 전달하는 것입니다.

나는 이것을 va_list와 함께 할 방법이 있어야한다고 생각했다.

하지만 어떻게?

나는이 예제를 사용하고, 더 간단한 활용하려면 다음

list<int> myList; 
myList.push_back(1); 
myList.push_back(5); 
myList.push_back(10); 
myList.push_back(37); 
myList.push_back(42); 

double function avg(int num, ...) 
    va_list arguments;      
    int sum = 0; 

    va_start (arguments, num);   
    for (int x = 0; x < num; x++)   
    { 
     sum += va_arg (arguments, int); 
    } 
    va_end (arguments); 

    return sum/num;  
} 

가 나는 목록에있어 모든 숫자와 avg를 호출합니다. 위에서 언급 한 튜토리얼에서 예제 함수를 사용했지만 간단히 말해야한다. 그러나 zend 프레임 워크의 일부이므로 호출 된 함수를 변경할 수 없습니다.

C 또는 C++에서이 작업을 수행 할 수있는 방법이 있습니까?


내 두번째 방법 :

string My1stParam; 
int My2ndParam; 
int My3rdParam; 

Zend::getMethodParams<string, int, int>("sii", &My1stParam, &My2ndParam, &My3rdParam); 

내가 그 일을해야한다고 생각하지만, 어려운 일이 :

template <typename... Arguments> 
size_t Zend::getMethodParams(string paramStr, Arguments... Args) 
{  
     if (zend_parse_parameters(
       ZEND_NUM_ARGS() TSRMLS_CC, , 
       paramStr.c_str(), 
       Args... 
       ) == FAILURE) 
     { 
      return 0; 
     } 
} 

하는 것은 다음과 같이 호출하려면 (3 개 매개 변수를 정의하세요) 그 문제 : zend_parse_parameters 함수는 문자열 (C 스타일 문자열!)에 대해 2 개의 값을 반환합니다. - 문자 포인터 및 - 문자열 길이.

그래서 나는 그런 식으로 전화를해야 할 것 중 하나

char* My1stParam_str; 
int My1stParam_length 
int My2ndParam; 
int My3rdParam; 

Zend::getMethodParams<string, int, int>("sii", &My1stParam_str, &My1stParam_length, &My2ndParam, &My3rdParam); 
string My1stParam; 
My1stParam.assign(My1stParam_str, My1stParam_length); 

을 어쨌든, 그게 내가 방지하기 위해 원하는 것을이었다.

또는 이러한 추가 단계를 내부적으로 수행하려면 zend_parse_parameters 함수에 전달 된 인수 목록을 수정해야합니다.

string My1stParam; 
int My2ndParam; 
int My3rdParam; 

Zend::getMethodParams<string, int, int>("sii", &My1stParam, &My2ndParam, &My3rdParam); 

그래서 명확하게 말 : 매개 변수는 컴파일 타임에 알려져 있지만, 함수 호출 모두에서 매우 다른 것입니다 내가 그런 식으로 적어도를 호출 할 수 바라고

이후의 소스 코드에서 발생.

+0

C++ 11은 옵션입니까? –

+0

예. 그렇습니다. 이걸로 어떤 방법이 있습니까? –

+0

Variadic 템플릿이 도움이 될 것입니다 –

답변

0

zend 프레임 워크 내에서이를 해결할 수있는 방법을 찾았습니다. 전에 실제로 그러한 해결책을 찾았지만, 문서화가 잘 안된 것 같습니다 (n.m. 이미 멘토링되었으므로 va_list를 사용하는 것과 같은 내부적 인 방법이 없습니다).

하지만 실제로는 하나입니다! 이 문제 stucking 다른 사용자에게는

:

의 해결책
long arg; 
zval ***args; 
int i, argc = ZEND_NUM_ARGS(); 

if (zend_parse_parameters(1 TSRMLS_CC, "l", &arg) == FAILURE) return; 

array_init(return_value); 
add_index_long(return_value, 0, arg); 

if(argc>1) { 
    args = (zval ***)emalloc(argc * sizeof(zval **)); 
    if(zend_get_parameters_array_ex(argc, args) == FAILURE) { 
     efree(args); 
     return; 
    } 
    for(i = 1; i < argc; i++) { 
     zval_add_ref(args[i]); 
     add_index_zval(return_value,i, *args[i]); 
    } 
    efree(args); 
} 

)

니펫, http://docstore.mik.ua/orelly/webprog/php/ch14_07.htm 발견은 PHP 배열의 C 표현에 동적으로 모든 파라미터를 파싱한다.

관련 문제