Утечка памяти в Adobe String - Где вызвать точку входа внешней библиотеки в свободную память? - PullRequest
1 голос
/ 08 апреля 2019

Я создал сценарий After Effects, который извлекает данные из файлов JSON, загруженных с URL-адреса HTTPS. Проблема в C ++ DLL, которую я закодировал, чтобы загрузить ее и передать обратно сценарию. Несмотря на то, что все работало нормально, был один случай утечки памяти - After Effects выпустил всплывающее сообщение «STRING MEMORY LEAK».

Я новичок в C ++, но мне удалось создать DLL, которая загружает файлы на основе примеров, поставляемых с установкой After Effects (samplelib и basicexternalobject), а также в документации Microsoft C ++. В Руководстве по инструментам Adobe JavaScript говорится, что метод «ESFreeMem ()» должен быть «вызван для освобождения памяти, выделенной для строки с нулевым символом в конце, передаваемой в или из библиотечных функций». Проблема в том, что я не знаю, как и где это использовать. Я использую After Effects CC 15.0.0 (сборка 180) на Windows 7.

Это функция C ++, которая получает некоторые параметры из вызывающей стороны javascript и возвращает строку с содержимым JSON. Если это не удается, он возвращает логическое значение (FALSE), чтобы скрипт мог делать то, что необходимо в этом случае.

extern "C" TvgAfx_Com_API long DownloadJson(TaggedData* argv, long argc, TaggedData * result)  
{  

     //... first I check the arguments passed  

// The returned value type  
result->type = kTypeString;  


//Converts from string into LPCWSTR ---------------------------------------------------  
std::wstring stemp = s2ws(argv[0].data.string);  
LPCWSTR jsonLink = stemp.c_str();  


std::wstring stemp02 = s2ws(argv[1].data.string);  
LPCWSTR jsonHeader = stemp02.c_str();  
//--------------------------------------------------------------------------------------  


//Class that does the HTTP request  
WinHttpClient client(jsonLink, jsonHeader);  


//Synchronous request   
if (client.SendHttpsRequest())  
{  
     string httpResponse = client.GetHttpResponse();  


     if (httpResponse.length() > 0)  
     {  
          //Sends response string back to javascript  
          result->data.string = getNewBuffer(httpResponse);  
     }  
     else  
     {  
           //Sends FALSE back to javascript  
           result->type = kTypeBool;  
           result->data.intval = 0;  
     }  
}  
else  
{  
     //Sends FALSE back to javascript  
     result->type = kTypeBool;  
     result->data.intval = 0;  
}  


return kESErrOK;  
}  

Класс WinHttpClient, который выполняет фактический запрос, освобождает память, выделенную для буфера, который содержит ответ. Вот кусок кода:

// Read the data.  
ZeroMemory(pszOutBuffer, dwSize + 1);  

if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded))  
{  
//Log error  
}  
else  
{  
resource.append(pszOutBuffer).c_str();  
}  


// Free the memory allocated to the buffer.  
delete[] pszOutBuffer;  

Это функция, используемая в примере Adobe для хранения строки, которая будет возвращена в javascript:

//brief Utility function to handle strings and memory clean up  
static char* getNewBuffer(string& s)  
{  
// Dynamically allocate memory buffer to hold the string   
// to pass back to JavaScript  
char* buff = new char[1 + s.length()];  


memset(buff, 0, s.length() + 1);  
strcpy(buff, s.c_str());  


return buff;  
}  

Теперь в руководстве сказано, что этот метод должен быть реализован:

/** 
* \brief Free any string memory which has been returned as function result. 
* JavaScipt calls this function to release the memory associated with the string. 
* Used for the direct interface. 
* 
* \param *p Pointer to the string 
*/  
extern "C" SAMPLIB void ESFreeMem (void* p)  
{  
if (p)  
free (p);  
}

Из этого я понимаю, что память, связанная с возвращенной строкой json, должна быть освобождена. Но разве класс запроса уже сделал это? Я просто не знаю, где вызвать этот метод и что ему передать. Буду признателен за любую помощь. Большое спасибо!

...