2017-12-30 58 views
-2

사용자 정의 데이터를 전달하기위한 포인터 인수 만 허용하는 C 스타일 API에 C++ 참조를 전달하려고합니다.포인터로 전달하기위한 C++ 참조 주소 가져 오기

필자는 단순히 "function"이라는 함수에서 발생하는 void에 대한 포인터로 C++ 참조의 주소를 캐스팅합니다. 이 포인터는 매개 변수로 콜백 함수를 사용하는 c 함수 ("실행")로 전달됩니다. 콜백 함수 구현 ("콜백") 내에서 void 포인터를 std :: vector에 대한 포인터로 캐스트합니다.

이 파일은 MS Visual Studio 2017에서 경고 및 오류없이 컴파일되고 desried로 실행됩니다 (벡터 "v"에는 1에서 5까지의 숫자가 포함되어 있으며 인쇄됩니다). 그러나 이것은 C++ 표준에 따라 유효합니다.

물론 글로벌 std :: vector 인스턴스를 사용할 수 있습니다. 그러나 어떤 경우에는 내 경우와 마찬가지로 이것이 나쁜 해결책 일 수 있습니다. 내 경우에는 내가 "함수"에 대한 호출 당 std :: vector의 인스턴스가 필요하므로 하나의 전역 인스턴스가 매개 변수를 대체하는 것이 적합하지 않습니다. 또한 전역 인스턴스가 스레드 당 호출 스택에 std :: vector의 인스턴스를 유지하려는 멀티 스레드 환경에서는 적절하지 않을 수 있습니다. std :: vector 인스턴스를 클래스로 래핑하고 포인터를 std :: vector 멤버에 전달하는 것은 실제로 내가 원하는 것이 아닙니다. 나는 오히려 내가 사용했던 특정 구현에 대한 기술적 견해에 대해 궁금해한다.

간단히 말해서이 예제를 나쁜 습관이라고 생각합니까? 참조 유형의 주소를으로 가져와 void에 대한 포인터에서 void 로의 포인터에서 유형으로 캐스팅했다가 원래 의도 한 포인터가 인 것을 무시하고 캐스팅합니다. 위에서 설명한 것들 대신에 대안이 있습니까?

아래 최소한의 작업 예를 찾아주세요 : 당신은 실제로 정의에 초기화 제외 참조 변수로 아무것도 할 수 없습니다

#include <vector> 
#include <iostream> 

// 
// The API of a 3rd party library (Typical C-Style Interface) 
// 

void execute(void (*callback)(void *, int[], int), void * context) 
{ 
    int data [5] = {1,2,3,4,5}; 

    (*callback)(context, data, 5); 
} 

// 
// My callback function fitting the signature for the 3rd party API 
// 

void callback(void * context, int data [], int size) 
{ 
    std::vector<int> * v = (std::vector<int> *)context; 

    for (int i = 0; i < size; i++) { 
     v->push_back(data[i]); 
    } 
} 

// 
// Pass a reference to an std::vector as void * to the 3rd party API 
// 

void function(std::vector<int> & v) 
{ 
    execute(callback, (void *)&v); 
} 

// 
// Pass a std::vector as reference to a function 
// 
// Evaluate the result at the end 
// 

int main() 
{ 
    std::vector<int> v; 

    function(v); 

    for (auto & e : v) { 
     std::cout << e << std::endl; 
    } 

    return 0; 
} 
+4

C- 스타일 API에 "참조"를 전달하지 않고, 평범한 오래된 포인터 (원래의 * 객체에'main' 함수의 벡터'v')를 전달합니다. –

+1

'& v'는'std :: vector *'유형입니다 - 벡터에 대한 포인터. '(void *)'캐스트를 삭제할 수 있으며, 잘 작동합니다. –

+0

예 "참조"를 전달하지 않는다는 것을 알고 있습니다. 그러나 나는 통과를위한 참조 주소를 취하고있다. 기본적으로 내가 요구하는이 작업의 유효성입니다. – user3272529

답변

0

합니다. 초기화 후에 참조 변수를 사용할 때마다 원래 변수에 직접 액세스 할 수 있습니다. 귀하의 경우에는

, 당신은 기능 function&v을 수행 할 때, 로컬 참조 변수 v의 주소,하지만 main 함수의 변수 v의 주소를하지 않습니다.

요약하면 이것은 괜찮습니다.