即使解码器被销毁,IWICImagingFactory :: CreateDecoderFromFilename()也会保持文件锁定

时间:2017-03-29 18:47:37

标签: c++ file share direct2d

我正在使用IWICImagingFactory::CreateDecoderFromFilename()进行阅读。有没有办法可以传递像FILE_SHARE_READ旗帜那样的东西?文件在上面的函数调用中保持打开状态,直到程序终止。

在同一程序中的另一个操作期间,我尝试使用CFile::Open(),但是我收到错误32(“进程无法访问该文件,因为它正由另一个进程使用”)。

2 个答案:

答案 0 :(得分:0)

我最终做的是使用

pImagePoolEntry->hFileHandle = CreateFile(
    path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
在致电CreateDecoderFromFilename()之前

由于我已经使用图像池跟踪已打开的共享图像,因此我刚刚添加了初始文件句柄并添加了代码,以便在图像不再使用时使用CloseHandle()

答案 1 :(得分:0)

我不确定IWICBitmapDecoder对该文件的作用,但它似乎是在Release()调用之后保持打开状态。它可能有一个错误,手柄没有关闭,谁知道。我找不到有关该行为的任何信息。实际上,除了这个问题,似乎没有人注意到(或没有人关心)。

在任何情况下,Tony提示的解决方案是手动打开文件并使用CreateDecoderFromFileHandle()代替CreateDecoderFromFilename()。请注意“文件句柄必须在解码器的生命周期内保持活动状态。”

所以这个:

void f(IWICImagingFactory* factory, const wchar_t* path)
{
    IWICBitmapDecoder* decoder = nullptr;

    factory->CreateDecoderFromFilename(
        path, nullptr, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &decoder);

    // ...

    decoder->Release();
}

成为这个:

void f(IWICImagingFactory* factory, const wchar_t* path)
{
    auto h = CreateFileW(
        path, GENERIC_READ, FILE_SHARE_READ,
        nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    IWICBitmapDecoder* decoder = nullptr;

    factory->CreateDecoderFromFileHandle(
        reinterpret_cast<ULONG_PTR>(h), nullptr,
        WICDecodeMetadataCacheOnLoad, &decoder);

    // ...

    decoder->Release();
    CloseHandle(h);
}