1

以下の「メイン」の2つのC#行で、低レベル/メモリ管理の観点から正確に何が起こっているのか説明できますか?

C++ コード (アンマネージ):

    #define DLLEXPORT extern "C" __declspec(dllexport)

    DLLEXPORT MyClass* MyClass_MyClass()
    {
        return new MyClass();
    }
    DLLEXPORT void MyClass_setName(MyClass* myClass, const char* name)
    { 
        myClass->setName(name);
    }

MyClass::MyClass()
{
    _name.clear();
}
void MyClass::setName(const char* name)
{
    _name.setCString(name, NAME_MAX_BYTES);
}

C# コード:

        [DllImport(@"lib.dll")]
        private static extern IntPtr MyClass_MyClass();
        [DllImport(@"lib.dll")]
        public static extern void MyClass_setName(
                    IntPtr myClass,
                    [System.Runtime.InteropServices.InAttribute()]
                    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
                    string name);

        public static void Main(string[] args)
        {
            var myClass = MyClass_MyClass();
            MyClass_setName(myClass , "Test Name");
        }

具体的には、「myClass」に割り当てるスペースを .NET がどのように認識しているのか疑問に思っています。バックグラウンドで何らかの「Marshal.AllocHGlobal(SIZE)」を実行しているはずですよね?より多くのスペースが必要な場合 (名前を設定しますか?) はどうなりますか? また、ガベージコレクションが発生してメモリが移動し、「IntPtr myClass」が台無しになるリスクはありますか?

4

2 に答える 2

1

.NETはMyClass型について何も知らず、型へのポインタのみを格納します。ポインタのサイズは常に既知であり、固定されています。32ビットプロセスの場合は4バイト、64ビットプロセスの場合は8バイトです。この特定の場合のすべてのメモリ割り当てと管理は、ここのアンマネージC++コードで行われます。

return new MyClass();

そしてここ:

myClass->setName(name);

メモリの割り当て/解放/管理方法を決定するのはこのC++DLL次第であり、C#コードはこのDLLのインポートされた関数を呼び出すだけです。

アンマネージドオブジェクトに対してガベージコレクションは実行されません。メモリリークを回避するために、オブジェクトを解放するための追加の(アンマネージド)メソッドを提供する必要があります。

于 2010-10-26T22:56:43.550 に答える
0

C++ コードが管理されていない場合、.net は IntPtr を超えて何も割り当てていません。C++ コードによって割り当てられています。

これは、その IntPtr でのみガベージ コレクションが実行されることを意味します。これは小さいため、ガベージ コレクターがクリーンアップを決定するまでに長い時間がかかる場合があります。

これが意味することは、C++ コードが適切にクリーンアップされたとしても、実際にクリーンアップを行うまでに長い時間がかかる可能性があるということです。C++ コードは大量のメモリを使用している可能性がありますが、.net からは見えないため、「より大きな」.net オブジェクトよりも優先してクリーンアップすることはありません。

于 2010-10-26T23:02:13.533 に答える