简体   繁体   English

需要对Windows API的智能指针有更好的了解

[英]Need a better understanding of smart pointers with windows API

I'm having a hard time understanding smart pointers (still in the beginning stages of learning tbh). 我很难理解智能指针(仍处于学习tbh的开始阶段)。 Maybe I've been starring at the problem too long and I'm missing the easy concept... 也许我一直在关注这个问题太久了,而我却错过了这个简单的概念...

I'm in the process of turning all my "new/deletes" into smart pointers so I don't have such a big issue with memory leaks/corruption. 我正在将所有“新/删除”都转换为智能指针,因此内存泄漏/损坏没有太大的问题。

With unique_ptr's you can't just: 使用unique_ptr,您不仅可以:

PCHAR test;
std::unique_ptr<char[]> buffer = std::make_unique<char[]>(10);
buffer.get() = test;

(Please correct me if I'm wrong) So instead, I'm passing a raw shared_ptr to get the address of bytes I need to look into PE Headers. (如果我错了,请纠正我)所以,我传递了一个raw_shared_ptr来获取需要查看PE标头的字节地址。 pFileBase will have the bytes "MZ" but my shared_ptr is not coming back with those bytes. pFileBase的字节将为“ MZ”,但我的shared_ptr没有返回这些字节。 What am I missing? 我想念什么?

Is there a way to have WinAPI functions return into a smart pointer? 有没有一种方法可以使WinAPI函数返回到智能指针? I'm also aware my shared_ptr is not char[] so that is my next step on fixing. 我也知道我的shared_ptr不是char [],所以这是修复的下一步。

BOOL InitializeFromDisk(std::wstring &wsTempPath, char *pFileBase)
{
 ...
 pFileBase = (PCHAR)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
 if (pFileBase == 0) return FALSE;
 return TRUE;
}
int main()
{
 std::shared_ptr<char> pFile = std::make_shared<char>(0);
 InitializeFromDisk(L"c:\\...", pFile.get());
 ...
 PIMAGE_DOS_SIGNATURE pDosHdr;
 std::copy(pFile, 2, pDosHdr); //I'm sure this line doesn't quit work yet 
}

I might do something like this. 我可能会做这样的事情。 Smart pointers have move constructors, so it's pretty efficient to return them, and doing so also yields better code. 智能指针具有移动构造函数,因此返回它们非常有效,这样做还可以产生更好的代码。 Note the use of the deleter argument in the shared_ptr constructor. 请注意在shared_ptr构造函数中使用deleter参数。

std::shared_ptr<VOID> InitializeFromDisk(const std::wstring& wsTempPath, char *pFileBase)
{
    ...
    auto pMappedFile = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
    if (pMappedFile == nullptr)
    {
        auto lastError = GetLastError();
        throw system_error(lastError, system_category());
    }
    return shared_ptr<VOID>(pMappedFile, [](auto p) { UnmapViewOfFile(p); });
}

In , most APIs do not return objects as plain memory. ,大多数API都不将对象作为普通内存返回。 Instead, they usually return either HANDLE s or object instances that derive from IUnknown . 相反,它们通常返回HANDLE或从IUnknown派生的对象实例。 To free the memory associated with a HANDLE , you will usually call CloseHandle . 要释放与HANDLE相关联的内存,通常将调用CloseHandle To free the memory associated with an IUnknown object, call ->Release() . 要释放与IUnknown对象关联的内存,请调用->Release() Some allocations require special release calls. 一些分配需要特殊的发布调用。 In your example, the pointer returned by MapViewOfFile must be deallocated with UnmapViewOfFile . 在您的示例中,必须将MapViewOfFile返回的指针与UnmapViewOfFile释放。

For the more common types of objects, smart pointer wrappers are implemented in the Microsoft::WRL library. 对于对象的更常见类型,智能指针包装器在Microsoft::WRL库中实现。 For example: 例如:

Microsoft::WRL::ComPtr<ID3D12Device> spDevice;
D3D12CreateDevice(..., IID_PPV_ARGS(&spDevice));

Microsoft::WRL::Wrappers::FileHandle shFile;
shFile = CreateFile2(...);

Both spDevice and shFile will be appropriately deallocated upon going out of scope. 超出范围时,将适当地重新分配spDeviceshFile

For other allocations, like the returned MapViewOfFile pointer, you'll have to create your own smart pointer/handle class. 对于其他分配,例如返回的MapViewOfFile指针,则必须创建自己的智能指针/句柄类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM