2017-06-26 170 views
1

私はC++/CLIの初心者です。
私はすでに、pin_ptrの機能がGCに指定されたオブジェクトを学習させないことを知っています。C++/CLI pin_ptrの正しい使い方

ここではmsdnの例を示します。
https://msdn.microsoft.com/en-us//library/1dz8byfh.aspx

// pin_ptr_1.cpp 
// compile with: /clr 
using namespace System; 
#define SIZE 10 

#pragma unmanaged 
// native function that initializes an array 
void native_function(int* p) { 
    for(int i = 0 ; i < 10 ; i++) 
    p[i] = i; 
} 
#pragma managed 

public ref class A { 
private: 
    array<int>^ arr; // CLR integer array 

public: 
    A() { 
     arr = gcnew array<int>(SIZE); 
    } 

    void load() { 
    pin_ptr<int> p = &arr[0]; // pin pointer to first element in arr 
    int* np = p; // pointer to the first element in arr 
    native_function(np); // pass pointer to native function 
    } 

    int sum() { 
     int total = 0; 
     for (int i = 0 ; i < SIZE ; i++) 
     total += arr[i]; 
     return total; 
    } 
}; 

int main() { 
    A^ a = gcnew A; 
    a->load(); // initialize managed array using the native function 
    Console::WriteLine(a->sum()); 
} 

聞く質問です。

いいえ、渡されたオブジェクト(arr)は固定されていませんか? メインロジックが動作しているにもかかわらず、アンマネージコード(native_function)が同期操作であり、C++/CLIコード(ロード)より前に終了したため

がある可能性があります。 (Aはメインのスタック変数、arrはAのメンバ変数なので、mainを実行している間は表示されるはずだと思います)

もしそうなら、ロードを呼び出す前にAが存在することをどのように保証できますか? (ネイティブコードで実行していない間だけ?)

int main() { 
    A^ a = gcnew A; 
    // I Think A or arr can be destroyed in here, if it is able to be destroyed in native_function. 
    a->load(); 
    ... 
} 

おかげで、事前インチ

+0

オブジェクトを固定すると、2つのことが保証されます.GCはそれを収集せず、GCはそれを再配置しません。配列要素を固定すると、配列全体を効果的に固定するので、この例では 'native_function'が実行されている間に' arr'が固定されます。また、 'a'は' a-> sum() '呼び出しで使用され、' a'は 'arr'に保持されるので収集できません。 –

答えて

0

ポインタを固定することによって解決される問題は、通常の並行性の問題ではありません。他のスレッドがあなたのネイティブ関数の実行を先取りすることはないかもしれません。ただし、ガベージコレクタを使用する必要があります。これは、.NETランタイムが適切であるとみなされるたびに発生する可能性があります。たとえば、システムがメモリ不足のため、実行時に配置されたオブジェクトを収集することになります。これは、ネイティブ関数が実行されている間に発生する可能性があります。ガベージコレクタは、使用している配列を再配置する可能性があります。

大雑把なルールは、すべての配列ポインタとすべての文字列ポインタをネイティブ関数に渡す前に固定することです。常に。それについて考えるのではなく、それを原則としてやってください。あなたのコードは、ピンインすることなく長い間うまく動作するかもしれませんが、ある日、不運が最も厄介なときに、あなたに悪いことが起こります。

関連する問題