gpt4 book ai didi

C# 调用返回指针的 C++ 方法。解释内存管理

转载 作者:太空宇宙 更新时间:2023-11-04 12:22:52 28 4
gpt4 key购买 nike

有人可以从低级别/内存管理的角度解释以下“Main”中的 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");
}

具体来说,我想知道 .NET 如何知道要为“myClass”分配多少空间?它必须在后台执行某种“Marshal.AllocHGlobal(SIZE)”,对吗?如果需要更多空间(我设置名称?)会怎样?此外,是否存在垃圾回收和移动内存并弄乱我的“IntPtr myClass”的风险?

最佳答案

.NET 对 MyClass 类型一无所知,它只存储指向它的指针。指针的大小始终是已知和固定的 - 32 位进程为 4 个字节,64 位进程为 8 个字节。在这种特殊情况下,所有内存分配和管理都发生在此处的非托管 C++ 代码中:

return new MyClass();

这里:

myClass->setName(name);

由这个 C++ DLL 决定如何分配/释放/管理内存,C# 代码将只调用这个 DLL 的导入函数。

不会对您的非托管对象执行垃圾回收,您需要提供额外的(非托管)方法来释放它以避免内存泄漏。

关于C# 调用返回指针的 C++ 方法。解释内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4028691/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com