Resources inside binary at runtime


#1

I need to add resources to binary files after they’ve been compiled. The idea is to inject XML (or a binary blob) into a .exe, .dll, .so, .app, .component etc on all platforms. Why ? i have a program that’s a WYSIWYG for synthesizers but the problem is with parameters in plugins, i can’t export the right amount of paramters at load time since i don’t know what document will be loaded later, and the host asks for parameters after giving me my state information, so it’s a impossible. So i came up with this idea that is used in SynthEdit, exporting a dll with the data injected into it. I managed to get it working on windows for example

void CtrlrWindows::exportWithDefaultPanel(XmlElement *elementToWrite)
{
	File	me = File::getSpecialLocation(File::currentExecutableFile);
	File	newMe;
	HANDLE	hResource;

	FileChooser fc("Write new binary here", me, me.getFileExtension());

	if (elementToWrite == nullptr)
	{
		_DBG("CtrlrWindows::exportMeWithNewResource no data to write");
	}

	if (fc.browseForFileToSave(true))
	{
		newMe = fc.getResult();

		if (!newMe.hasFileExtension(me.getFileExtension()))
		{
			newMe = newMe.withFileExtension(me.getFileExtension());
		}

		if (me.copyFileTo (newMe))
		{
			_DBG("CtrlrWindows::exportMeWithNewResource success");
		}
		else
		{
			_DBG("CtrlrWindows::exportMeWithNewResource failed");
			return;
		}
	}

	_DBG("CtrlrWindows::exportMeWithNewResource writing a copy of [" + me.getFullPathName() + "] to [" + newMe.getFullPathName() + "]");

	hResource = BeginUpdateResource(newMe.getFullPathName().toUTF8(), FALSE);

	if (NULL != hResource)
	{
		String textData = elementToWrite->createDocument(String::empty);
		MemoryBlock data (textData.toUTF8().getAddress(), textData.length());

		_DBG("CtrlrWindows::exportMeWithNewResource writing resource of size="+String(data.getSize()));

		if (UpdateResource(hResource, RT_RCDATA, MAKEINTRESOURCE(103), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPVOID) data.getData(), data.getSize()) != FALSE)
		{
			_DBG("CtrlrWindows::exportMeWithNewResource WIN32 UpdateResource() completed");

			EndUpdateResource(hResource, FALSE);
		}
		else
		{
			_DBG("CtrlrWindows::exportMeWithNewResource WIN32 UpdateResource() failed");
		}
	}
	else
	{
		_DBG("CtrlrWindows::exportMeWithNewResource WIN32 BeginUpdateResource() failed");
	}
}

Now i want to do the same for Linux and OSX. On OSX it seems easy since the application packages are directories, each of the has a Resource dir inside that contains the icons (if it’s a .app bundle). But i was wondering if there are some native OSX calls to do that, instead just loading files from a relative path to the UNIX binary file ? Are there any framework calls for that.

And for linux i know i need to go into ELF and probably use one of the ELF libraries to manage my binaries, but has anyone any experience in witch one works the best, and witch section of the ELF is best suited for that (have in mind that the data i’m injecting can be very large, up to few megabytes since it will contain fonts, images, audio files etc).

Any ideas, maybe someone has already done something similar ?


#2

I did something like this before, but not with Juce. I wrote a little command line app that would embed some data into a precompiled .exe. The data I embedded into the .exe contained information on how the application would appear. On start-up the .exe would open an image of itself and search for a unique identifier. When it found it it would read n bytes of info and then dynamically set up its GUI. Is this the kind of thing you are talking about? I imagine it would be a lot more straightforward with Juce. I can remember having some issue with portability. In the end it worked on all systems, but I remember thinking at the time that there must be an easier way to do it!