我创建了一个After Effects脚本,从HTTPS URL下载的JSON文件中提取数据。问题出在我编写的C++ DLL上,我把它下载并传回脚本。尽管它一直工作正常,但有一次出现了内存泄漏的情况--After Effects发出了 "STRING MEMORY LEAK "的弹窗。
我是个C++新手,但我根据After Effects安装时提供的例子(samplelib和basicexternalobject)以及微软的C++文档,设法编写了一个下载文件的DLL。Adobe JavaScript工具指南中说,必须 "调用 "ESFreeMem() "方法来释放为传递给库函数或从库函数传来的空端字符串分配的内存"。问题是我不知道如何或在哪里使用它。我在Windows 7上使用After Effects CC 15.0.0(build 180)。
这是一个C++函数,它从javascript调用者那里获取一些参数,然后返回一个包含JSON内容的字符串。如果失败了,它会返回一个bool(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字符串相关的内存必须被释放。但是请求类不是已经做到了吗?我只是不知道该在哪里调用这个方法,该把什么传给它。我将感激任何帮助。非常感谢
当你为After Effects创建一个DLL ExternalObject时,它实际上只是一个接口,你可以通过一些ExtendScript脚本来调用。 你必须在AE脚本中加载ExternalObject,一旦加载,你在C++类中创建的方法函数就可以从脚本中调用。
你必须知道 如何在ExtendScript脚本文件中加载DLL。. 然后,你可以调用DLL的方法。