As my update said, a dict entry has to be in an array, but it doesn't have to be the only element in the array. For instance, PulseAudio's loopback module takes command line arguments like this:
$pactl load-module module-loopback source="alsa_input.pci-0000_00_1b.0.analog-stereo" sink="bluez_sink.10_B7_F6_02_1B_4A"
In order to send this over DBUS, the loadModule() function requires a string and two dict entries, each containing a string key ("source" or "sink") and a string value ("name of device"). Note that the string value is NOT THE DEVICE'S PULSEAUDIO PATH, as I first suspected. It's the same string as is used with pactl. In order to create the s{ss}{ss} arguments, the dict entries first have to be encapsulated in an array: s[{ss}{ss}]. The iterator commands follow:
//append arguments to the Set() method. (string interface, string property, value)
dbus_message_iter_init_append(msg, &msgIter);
//string
dbus_message_iter_append_basic(&msgIter, DBUS_TYPE_STRING,&moduleName);
//array
dbus_message_iter_open_container(&msgIter,DBUS_TYPE_ARRAY,"{ss}{ss}",&arrayIter);
//dict entry
dbus_message_iter_open_container(&arrayIter, DBUS_TYPE_DICT_ENTRY, NULL, &dictIter1);
//strings
dbus_message_iter_append_basic(&dictIter1, DBUS_TYPE_STRING, &sourceStr);
dbus_message_iter_append_basic(&dictIter1, DBUS_TYPE_STRING, &sourceName);
//close dict entry
dbus_message_iter_close_container(&arrayIter, &dictIter1);
//dict entry
dbus_message_iter_open_container(&arrayIter, DBUS_TYPE_DICT_ENTRY, NULL, &dictIter2);
//strings
dbus_message_iter_append_basic(&dictIter2, DBUS_TYPE_STRING, &sinkStr);
dbus_message_iter_append_basic(&dictIter2, DBUS_TYPE_STRING, &sinkName);
//close dict entry
dbus_message_iter_close_container(&arrayIter, &dictIter2);
//close array
dbus_message_iter_close_container(&msgIter, &arrayIter);