Anonymous
Приложение аварийно завершилось при неявно объявленном операторе = [закрыто]
Сообщение
Anonymous » 28 окт 2024, 09:15
Я создал следующий класс «TestImageEncoder», активировал его и вызвал «EncodeData()» 16 раз в методе «TestProcess», который также вызывается примерно 20 раз.
MyApp внезапно исчез. произошел сбой, и когда я увидел аварийный дамп, я обнаружил, что TestImageEncoder::operator= является точкой сбоя.
Я знаю, что оператор = должен быть объявлен неявно, но я не использую '=' для TestImageEncoder как вы можете увидеть в TestProcess().
Почему был вызван неявный оператор =? где?
Не могли бы вы объяснить мне, что произошло в моем коде?
TestImageEncoder предназначен для кодирования данных изображения с помощью кодека Jpeg XR, который проверен компонентом обработки изображений Windows ( WIC).
"TestImageEncoder.h" в моей подбиблиотеке приложения
Код: Выделить всё
#pragma once
#include "wincodec.h"
#include "wincodecsdk.h"
class AFX_EXT_CLASS TestImageEncoder
{
private:
IWICImagingFactory* mpFactory;
public:
TestImageEncoder();
virtual ~TestImageEncoder();
BOOL Initialize();
BOOL EncodeData( WORD* pImage, int width, int height, BYTE** pDstData, int& dstSize, BOOL isLossless );
};
"TestImageEncoder.cpp" в моей подбиблиотеке dll приложения
Код: Выделить всё
TestImageEncoder::TestImageEncoder()
: mpFactory( NULL )
{
Initialize();
}
TestImageEncoder::~TestImageEncoder()
{
if ( mpFactory )
{
mpFactory->Release();
mpFactory = NULL;
}
CoUninitialize();
}
BOOL TestImageEncoder::Initialize()
{
// Initialize COM
HRESULT hr;
hr = CoInitialize( NULL );
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed CoInitialize(): %d\n", hr );
return FALSE;
}
// Create the COM imaging factory
hr = CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &mpFactory ) );
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to create a WIC imaging factory: %d\n", hr );
return FALSE;
}
return TRUE;
}
BOOL TestImageEncoder::EncodeData( WORD* pImage, int width, int height, BYTE** ppDstData, int& dstSize, BOOL isLossless )
{
// Encode image data and save it as JPEG XR file
CString tempFullPath;
tempFullPath = _T( "TempImage.jxr" );
BOOL res = SaveAsJpegXR( tempFullPath, pImage, width, height, isLossless );
if ( !res )
{
// Delete the JPEG XR file
::DeleteFile( tempFullPath );
return FALSE;
}
// Load image data from the JPEG XR file
CFile jxrFile;
jxrFile.Open( tempFullPath, CFile::modeRead );
dstSize = jxrFile.GetLength();
*ppDstData = new BYTE[dstSize];
ZeroMemory( *ppDstData, dstSize );
jxrFile.Read( *ppDstData, dstSize );
jxrFile.Close();
// Delete the JPEG XR file
::DeleteFile( tempFullPath );
}
BOOL TestImageEncoder::SaveAsJpegXR( CString& filePath, WORD* pImage, int width, int height, BOOL isLossless )
{
HRESULT hr;
IWICStream* piStream = NULL;
IWICBitmapEncoder* piEncoder = NULL;
IWICBitmapFrameEncode* piBitmapFrame = NULL;
IPropertyBag2* pPropertybag = NULL;
BOOL res = FALSE;
__try
{
// Create a stream //////////////////////////////////////////////
hr = mpFactory->CreateStream( &piStream );
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to create stream: %d\n", hr );
res = FALSE;
__leave;
}
piStream->InitializeFromFilename( filePath, GENERIC_WRITE );
// Create an encoder //////////////////////////////////////////////
hr = mpFactory->CreateEncoder( GUID_ContainerFormatWmp, NULL, &piEncoder );
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to create encoder: %d\n", hr );
res = FALSE;
__leave;
}
// Initialize the encoder ///////////////////////////
hr = piEncoder->Initialize( piStream, WICBitmapEncoderNoCache );
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to initialize encoder: %d\n", hr );
res = FALSE;
__leave;
}
// Create a frame ///////////////////////////////////////////////////
hr = piEncoder->CreateNewFrame( &piBitmapFrame, &pPropertybag );
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to create a new frame: %d\n", hr );
res = FALSE;
__leave;
}
// Set lossless if it is true /////////////////////////////////////////
if ( isLossless )
{
// Enable lossless /////////////////////////////
PROPBAG2 option = { 0 };
option.pstrName = L"Lossless";
VARIANT varValue;
VariantInit( &varValue );
varValue.vt = VT_BOOL;
varValue.bVal = VARIANT_TRUE;
hr = pPropertybag->Write( 1, &option, &varValue );
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to set the property for Lossless: %d\n", hr );
res = FALSE;
__leave;
}
}
// Initialize the frame ///////////////////////////////////////////////////
hr = piBitmapFrame->Initialize( pPropertybag );
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to initialize the frame: %d\n", hr );
res = FALSE;
__leave;
}
// Set image size ///////////////////////////////////////////////////
hr = piBitmapFrame->SetSize( width, height );
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to set size (width=%d, height=%d) : %d\n", width, height, hr );
res = FALSE;
__leave;
}
// Set the pixel format ///////////////////////////////////////////////////
WICPixelFormatGUID formatGUID = GUID_WICPixelFormat16bppGray;
hr = piBitmapFrame->SetPixelFormat( &formatGUID );
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to set pixel format: %d\n", hr );
res = FALSE;
__leave;
}
// Check if the pixel format is correctly set //////////////////////////
hr = IsEqualGUID( formatGUID, GUID_WICPixelFormat16bppGray ) ? S_OK : E_FAIL;
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Unexpected pixel format (not 16bppGray): %d\n", hr );
res = FALSE;
__leave;
}
UINT cbStride = width * sizeof( WORD );
UINT cbBufferSize = height * cbStride;
hr = piBitmapFrame->WritePixels( height, cbStride, cbBufferSize, (BYTE*)pImage );
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to write image data: %d\n", hr );
res = FALSE;
__leave;
}
hr = piBitmapFrame->Commit();
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to commit the frame: %d\n", hr );
res = FALSE;
__leave;
}
hr = piEncoder->Commit();
if ( FAILED( hr ) )
{
_RPTN( _CRT_WARN, "Failed to commit the encoder: %d\n", hr );
res = FALSE;
__leave;
}
res = TRUE;
}
__finally
{
if ( piEncoder )
{
piEncoder->Release();
}
if ( piBitmapFrame )
{
piBitmapFrame->Release();
}
if ( pPropertybag )
{
pPropertybag->Release();
}
if ( piStream )
{
piStream->Release();
}
}
return res;
}
Метод в моем exe-файле приложения
Код: Выделить всё
void TestProcess(WORD* srcData, int width, int height)
{
CFile fImage;
fImage.Open( "TestImageData.DAT", CFile::modeWrite | CFile::modeCreate );
int srcSize = wBytes_per_Pixel * dwWidth * dwHeight;
BYTE* pDst = NULL;
int dstSize = 0;
TestImageEncoder encoder;
for ( int i = 0; i < 16; i++ )
{
encoder.EncodeData( srcData, width, height, &pDst, dstSize );
fImage.Write( &dstSize, sizeof( int ) );
fImage.Write( pDst, dstSize );
delete[] pDst;
pDst = NULL;
}
}
Частично извлеченный дамп сбоя выглядит следующим образом.
mfc140u!CWnd::OnWndMsg+0xe75
mfc140u!CWnd::WindowProc+0x3f
mfc140u!AfxCallWndProc+0x11e
mfc140u!AfxWndProc+0x54
mfc140u!AfxWndProcBase+0x49
user32!UserCallWinProcCheckWow+0x2d1
user32!DispatchMessageWorker+0x1f1 mfc140u!AfxInternalPumpMessage+0x52
mfc140u!CWinThread::Run+0x81
mfc140u!AfxWinMain+0xc0
MyApp!TestImageEncoder::operator=+0x5af62 kernel32!BaseThreadInitThunk+0x1d
ntdll!RtlUserThreadStart+0x28
Подробнее здесь: https://stackoverflow.com/questions/791 ... d-operator
1730096154
Anonymous
Я создал следующий класс «TestImageEncoder», активировал его и вызвал «EncodeData()» 16 раз в методе «TestProcess», который также вызывается примерно 20 раз. MyApp внезапно исчез. произошел сбой, и когда я увидел аварийный дамп, я обнаружил, что TestImageEncoder::operator= является точкой сбоя. Я знаю, что оператор = должен быть объявлен неявно, но я не использую '=' для TestImageEncoder как вы можете увидеть в TestProcess(). Почему был вызван неявный оператор =? где? Не могли бы вы объяснить мне, что произошло в моем коде? TestImageEncoder предназначен для кодирования данных изображения с помощью кодека Jpeg XR, который проверен компонентом обработки изображений Windows ( WIC). "TestImageEncoder.h" в моей подбиблиотеке приложения [code]#pragma once #include "wincodec.h" #include "wincodecsdk.h" class AFX_EXT_CLASS TestImageEncoder { private: IWICImagingFactory* mpFactory; public: TestImageEncoder(); virtual ~TestImageEncoder(); BOOL Initialize(); BOOL EncodeData( WORD* pImage, int width, int height, BYTE** pDstData, int& dstSize, BOOL isLossless ); }; [/code] "TestImageEncoder.cpp" в моей подбиблиотеке dll приложения [code]TestImageEncoder::TestImageEncoder() : mpFactory( NULL ) { Initialize(); } TestImageEncoder::~TestImageEncoder() { if ( mpFactory ) { mpFactory->Release(); mpFactory = NULL; } CoUninitialize(); } BOOL TestImageEncoder::Initialize() { // Initialize COM HRESULT hr; hr = CoInitialize( NULL ); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed CoInitialize(): %d\n", hr ); return FALSE; } // Create the COM imaging factory hr = CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &mpFactory ) ); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to create a WIC imaging factory: %d\n", hr ); return FALSE; } return TRUE; } BOOL TestImageEncoder::EncodeData( WORD* pImage, int width, int height, BYTE** ppDstData, int& dstSize, BOOL isLossless ) { // Encode image data and save it as JPEG XR file CString tempFullPath; tempFullPath = _T( "TempImage.jxr" ); BOOL res = SaveAsJpegXR( tempFullPath, pImage, width, height, isLossless ); if ( !res ) { // Delete the JPEG XR file ::DeleteFile( tempFullPath ); return FALSE; } // Load image data from the JPEG XR file CFile jxrFile; jxrFile.Open( tempFullPath, CFile::modeRead ); dstSize = jxrFile.GetLength(); *ppDstData = new BYTE[dstSize]; ZeroMemory( *ppDstData, dstSize ); jxrFile.Read( *ppDstData, dstSize ); jxrFile.Close(); // Delete the JPEG XR file ::DeleteFile( tempFullPath ); } BOOL TestImageEncoder::SaveAsJpegXR( CString& filePath, WORD* pImage, int width, int height, BOOL isLossless ) { HRESULT hr; IWICStream* piStream = NULL; IWICBitmapEncoder* piEncoder = NULL; IWICBitmapFrameEncode* piBitmapFrame = NULL; IPropertyBag2* pPropertybag = NULL; BOOL res = FALSE; __try { // Create a stream ////////////////////////////////////////////// hr = mpFactory->CreateStream( &piStream ); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to create stream: %d\n", hr ); res = FALSE; __leave; } piStream->InitializeFromFilename( filePath, GENERIC_WRITE ); // Create an encoder ////////////////////////////////////////////// hr = mpFactory->CreateEncoder( GUID_ContainerFormatWmp, NULL, &piEncoder ); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to create encoder: %d\n", hr ); res = FALSE; __leave; } // Initialize the encoder /////////////////////////// hr = piEncoder->Initialize( piStream, WICBitmapEncoderNoCache ); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to initialize encoder: %d\n", hr ); res = FALSE; __leave; } // Create a frame /////////////////////////////////////////////////// hr = piEncoder->CreateNewFrame( &piBitmapFrame, &pPropertybag ); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to create a new frame: %d\n", hr ); res = FALSE; __leave; } // Set lossless if it is true ///////////////////////////////////////// if ( isLossless ) { // Enable lossless ///////////////////////////// PROPBAG2 option = { 0 }; option.pstrName = L"Lossless"; VARIANT varValue; VariantInit( &varValue ); varValue.vt = VT_BOOL; varValue.bVal = VARIANT_TRUE; hr = pPropertybag->Write( 1, &option, &varValue ); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to set the property for Lossless: %d\n", hr ); res = FALSE; __leave; } } // Initialize the frame /////////////////////////////////////////////////// hr = piBitmapFrame->Initialize( pPropertybag ); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to initialize the frame: %d\n", hr ); res = FALSE; __leave; } // Set image size /////////////////////////////////////////////////// hr = piBitmapFrame->SetSize( width, height ); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to set size (width=%d, height=%d) : %d\n", width, height, hr ); res = FALSE; __leave; } // Set the pixel format /////////////////////////////////////////////////// WICPixelFormatGUID formatGUID = GUID_WICPixelFormat16bppGray; hr = piBitmapFrame->SetPixelFormat( &formatGUID ); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to set pixel format: %d\n", hr ); res = FALSE; __leave; } // Check if the pixel format is correctly set ////////////////////////// hr = IsEqualGUID( formatGUID, GUID_WICPixelFormat16bppGray ) ? S_OK : E_FAIL; if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Unexpected pixel format (not 16bppGray): %d\n", hr ); res = FALSE; __leave; } UINT cbStride = width * sizeof( WORD ); UINT cbBufferSize = height * cbStride; hr = piBitmapFrame->WritePixels( height, cbStride, cbBufferSize, (BYTE*)pImage ); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to write image data: %d\n", hr ); res = FALSE; __leave; } hr = piBitmapFrame->Commit(); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to commit the frame: %d\n", hr ); res = FALSE; __leave; } hr = piEncoder->Commit(); if ( FAILED( hr ) ) { _RPTN( _CRT_WARN, "Failed to commit the encoder: %d\n", hr ); res = FALSE; __leave; } res = TRUE; } __finally { if ( piEncoder ) { piEncoder->Release(); } if ( piBitmapFrame ) { piBitmapFrame->Release(); } if ( pPropertybag ) { pPropertybag->Release(); } if ( piStream ) { piStream->Release(); } } return res; } [/code] Метод в моем exe-файле приложения [code]void TestProcess(WORD* srcData, int width, int height) { CFile fImage; fImage.Open( "TestImageData.DAT", CFile::modeWrite | CFile::modeCreate ); int srcSize = wBytes_per_Pixel * dwWidth * dwHeight; BYTE* pDst = NULL; int dstSize = 0; TestImageEncoder encoder; for ( int i = 0; i < 16; i++ ) { encoder.EncodeData( srcData, width, height, &pDst, dstSize ); fImage.Write( &dstSize, sizeof( int ) ); fImage.Write( pDst, dstSize ); delete[] pDst; pDst = NULL; } } [/code] Частично извлеченный дамп сбоя выглядит следующим образом. [list] [*]mfc140u!CWnd::OnWndMsg+0xe75 [*]mfc140u!CWnd::WindowProc+0x3f [*]mfc140u!AfxCallWndProc+0x11e [*]mfc140u!AfxWndProc+0x54 mfc140u!AfxWndProcBase+0x49 [*]user32!UserCallWinProcCheckWow+0x2d1 [*]user32!DispatchMessageWorker+0x1f1[*]mfc140u!AfxInternalPumpMessage+0x52 [*]mfc140u!CWinThread::Run+0x81 [*]mfc140u!AfxWinMain+0xc0 [*][b]MyApp!TestImageEncoder::operator=+0x5af62 kernel32!BaseThreadInitThunk+0x1d [*]ntdll!RtlUserThreadStart+0x28 [/list] Подробнее здесь: [url]https://stackoverflow.com/questions/79125366/app-crashed-at-implicitly-declared-operator[/url]