2017-12-30 54 views
-2

カスタムデータを渡すためのポインタ引数のみを許可するCスタイルのAPIへのC++参照を渡したいと思います。ポインタに渡すためのC++参照のアドレスの取得

私の例では、単純にvoidへのポインタにC++参照のアドレスをキャストします(これは "function"という関数で行われます)。このポインタはc関数( "execute"と呼ばれます)に渡され、コールバック関数をパラメータとして受け取ります。コールバック関数の実装( "コールバック")では、voidへのポインタをstd :: vectorへのポインタにキャストします。

これは警告なしでコンパイル(S)とMSのVisual Studio 2017とdesriedとして実行中にエラー(S)(ベクトル "vが" 1から5までの数字が含まれていると、彼らはまた、印刷されます)。しかし、私は恐れているこれはC + +の標準に従って有効です。

もちろん、グローバルstd :: vectorインスタンスを使用する可能性があります。しかし、状況によっては、私の場合のように、これは悪い解決策かもしれません。私の場合、私はstd :: vectorのインスタンスを "function"にする必要があるので、1つのグローバルインスタンスでパラメータを置き換えることは適切ではありません。また、マルチスレッド環境ではグローバルなインスタンスが不適切かもしれません。スレッドごとに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のアドレスを得ることはありません。

要するに、これは問題ありません。

関連する問題