Skip to main content
Another_Andrew
Inspiring
August 14, 2014
Answered

[CS6] [InDesign SDK] Any way to export SWF without a memory leak?

  • August 14, 2014
  • 2 replies
  • 840 views

I'm using part of a code sample found in the sample file SnpExportDynamicDocument.cpp that goes:

ErrorCode SnpExportDynamicDocument::ExportSWF(const UIDRef & documentUIDRef, IDFile& swfFileName)
{
ErrorCode status = kFailure;
InterfacePtr<IPMStream> outStream(StreamUtil::CreateFileStreamWriteLazy(swfFileName, kOpenOut | kOpenTrunc));

SDKFileHelper fileHelper(swfFileName);
if (fileHelper.GetPath().empty())
{
  ASSERT_FAIL("Invalid or missing filename.");
  return kFailure;
}

// create the SWF export action command
InterfacePtr<ICommand> swfExportCmd(CmdUtils::CreateCommand(kSWFExportCommandBoss));
if (swfExportCmd == nil)
{
  ASSERT(swfExportCmd);
  return kFailure;;
}

// Set Target
UIDList items(documentUIDRef.GetDataBase());
InterfacePtr<IPageList const> pageList(documentUIDRef, UseDefaultIID());
for (int32 pageIndex = 0, pageCount = pageList->GetPageCount(); pageIndex < pageCount; ++pageIndex)
  items.Append(pageList->GetNthPageUID(pageIndex));
swfExportCmd->SetItemList(items);


// Set cmd data
// IID_IDYNDOCSEXPORTCOMMANDDATA
InterfacePtr<IDynamicDocumentsExportCommandData> dynamicDocsCmdData(swfExportCmd, UseDefaultIID());
dynamicDocsCmdData->SetStream(outStream);
dynamicDocsCmdData->SetUIFlags(kSuppressUI);

// IID_ISWFEXPORTPREFERENCES
InterfacePtr<ISWFExportPreferences> swfCmdData(swfExportCmd, UseDefaultIID());
InterfacePtr<IWorkspace> iAppWS(GetExecutionContextSession()->QueryWorkspace());
InterfacePtr<ISWFExportPreferences> iSWFExportPrefs(iAppWS, UseDefaultIID());
swfCmdData->Copy(iSWFExportPrefs);


// process the command
return CmdUtils::ProcessCommand(swfExportCmd);

}

It leaks on the very last line. That is, if I remove the ProcessCommand() then there's no memory leak.

There appear to be "2 leaks, 130072 bytes" leaked every time I call the above.

I'm just pasting sample code that comes with CS6 SDK, so I can't see what the problem is.

I've checked the code in

Any suggestions?

This topic has been closed for replies.
Correct answer Bartek_Kropaczewski

it could be also bug in InDesign. Can you check if you have most up-to-date version of ID? 8.0.2.413

SDK Build 406

2 replies

Bartek_Kropaczewski
Inspiring
August 14, 2014

I double checked your code and there's no memory leaks. It must be something else.

I have tested that on ID CS 6 Mac and ID CC 2014 Mac

Regards

Bartek

Another_Andrew
Inspiring
August 15, 2014

It's disconcerting that you didn't encounter a leak. Being sceptical of my code elsewhere, I re-wrote the sample to be completely self-contained. I still have a memory leak, but if something is going wrong then it's all limited to just the following code:

ErrorCode ExportSWF_MemoryLeak()

{

IDocument* frontDocument = Utils<ILayoutUIUtils>()->GetFrontDocument();

if (frontDocument == nil) return kFailure;

UIDRef documentUIDRef = ::GetUIDRef(frontDocument);

if (documentUIDRef == kInvalidUIDRef) return kFailure;

//

AFile swfAFile("/Users/localadmin/Documents/ExportSWF.swf");

IDFile swfFileName(swfAFile);

//

ErrorCode status = kFailure;

InterfacePtr<IPMStream> outStream(StreamUtil::CreateFileStreamWriteLazy(swfFileName, kOpenOut | kOpenTrunc));

SDKFileHelper fileHelper(swfFileName);

if (fileHelper.GetPath().empty())

{

ASSERT_FAIL("Invalid or missing filename.");

return kFailure;

}

// create the SWF export action command

InterfacePtr<ICommand> swfExportCmd(CmdUtils::CreateCommand(kSWFExportCommandBoss));

if (swfExportCmd == nil)

{

ASSERT(swfExportCmd);

return kFailure;;

}

// Set Target

UIDList items(documentUIDRef.GetDataBase());

InterfacePtr<IPageList const> pageList(documentUIDRef, UseDefaultIID());

for (int32 pageIndex = 0, pageCount = pageList->GetPageCount(); pageIndex < pageCount; ++pageIndex)

items.Append(pageList->GetNthPageUID(pageIndex));

swfExportCmd->SetItemList(items);

// Set cmd data

// IID_IDYNDOCSEXPORTCOMMANDDATA

InterfacePtr<IDynamicDocumentsExportCommandData> dynamicDocsCmdData(swfExportCmd, UseDefaultIID());

dynamicDocsCmdData->SetStream(outStream);

dynamicDocsCmdData->SetUIFlags(kSuppressUI);

// IID_ISWFEXPORTPREFERENCES

InterfacePtr<ISWFExportPreferences> swfCmdData(swfExportCmd, UseDefaultIID());

InterfacePtr<IWorkspace> iAppWS(GetExecutionContextSession()->QueryWorkspace());

InterfacePtr<ISWFExportPreferences> iSWFExportPrefs(iAppWS, UseDefaultIID());

swfCmdData->Copy(iSWFExportPrefs);

// process the command

return CmdUtils::ProcessCommand(swfExportCmd);

}

At the top I grab the front document to get the document uid, and I also hard code the file path. These replace the parameters that were previously passed in. (Note if you do test the above that you should change the path to something that exists on your machine.)

@Bartek I've not replied to your other comment because I'm still working on that. My early result is a problem in the K2Memory namespace. I'm still researching what this means.

Bartek_Kropaczewski
Bartek_KropaczewskiCorrect answer
Inspiring
August 15, 2014

it could be also bug in InDesign. Can you check if you have most up-to-date version of ID? 8.0.2.413

SDK Build 406

Bartek_Kropaczewski
Inspiring
August 14, 2014

I assume this is caused by IPageList. You can try one of following steps:

1) pageList->Release();

    pageList.forget();

2) move "Set target" to other method

3) use memory tracker to find exact place where this code leaking.

Regards

Bartek

Another_Andrew
Inspiring
August 15, 2014

To respond to some of your suggestions.

1) Trying

pageList->Release();

pageList.forget();

Didn't improve things. The page list is wrapt in an InterfacePtr<> so doing things manually don't seem to help.

2) Not sure what you mean by "Set Target". Whenever I think of setting the target I think of setting the OS target. But I don't think you mean that.

3) I've been trying to make heads or tails of the memory tracker report.

I can't see any familiar class types within the report. I had thought that some of the hex number might have been references to class IDs but they appear to be just locations in memory.

Sorry. It's my first time looking over the output from memory tracker so it's all very new to me. Here's the full report if you're curious:

Leaks! 2 leaks, 130072 bytes

If you suspect that these leaks happened during a test you should compare these

allocation numbers with the starting and ending marks reported in

QA > Logs > MemoryUsage.txt

Alloc #863709: 65036 bytes at: 0x5ea12c00

K2Memory::RTLCompatibleDeleteDelegate(void*)(0x9d4c46)

K2Memory::RTLCompatibleDeleteDelegate(void*)(0x9d4d04)

K2Memory::RTLCompatibleMalloc(unsigned long)(0x9df90d)

MemoryPool::Allocate(unsigned long long, void*)(0x9d86fd)

GRUser::PurgeCallback(long, void*, short)(0x1d8e1dd)

_BIBTerminate(0x121ed67)

_BIBTerminate(0x121e0eb)

(null)(0x12791e9)

_CTInit(0x12c6d39)

(null)(0x12770ff)

(null)(0x1269a39)

_CTInit(0x141bf25)

_CTInit(0x14188f8)

_CTInit(0x141af26)

_CTInit(0x1404b6f)

_CTInit(0x1404e5d)

_CTInit(0x141c921)

_CTInit(0x141cb0f)

(null)(0x1270d01)

_CTInit(0x1353d3e)

_CTInit(0x12d3014)

_CTInit(0x12d379b)

_CTInit(0x12d0ebb)

_CTInit(0x12d19bd)

_CTInit(0x12d5e90)

Alloc #969847: 65036 bytes at: 0x438f2200

K2Memory::RTLCompatibleDeleteDelegate(void*)(0x9d4c46)

K2Memory::RTLCompatibleDeleteDelegate(void*)(0x9d4d04)

K2Memory::RTLCompatibleMalloc(unsigned long)(0x9df90d)

MemoryPool::Allocate(unsigned long long, void*)(0x9d86fd)

GRUser::PurgeCallback(long, void*, short)(0x1d8e1dd)

_BIBTerminate(0x121ed67)

_BIBTerminate(0x121e0eb)

_ACEInitialize(0xa8edca)

(null)(0xa45a7b)

(null)(0xa68ba4)

(null)(0xa6c06a)

(null)(0xa7a9df)

(null)(0xa8263a)

(null)(0xa84ac0)

(null)(0xa534b4)

(null)(0xa537c7)

_ACEInitialize(0xafde53)

_ACEInitialize(0xa920c1)

_AGMInitialize(0xbff272)

_AGMInitialize(0xeb8991)

_AGMInitialize(0xf5aa39)

_AGMInitialize(0xf75272)

_AGMInitialize(0xf78a46)

_AGMInitialize(0xf79be9)

_AGMInitialize(0xe6e385)

Legend
August 15, 2014

Without better symbols looking at those stacks is like reading tea leaves.

Anyway, retry with a different document that uses other fonts. At least those references to  _CTInit point towards the "CoolType" font subsystem.

Dirk