For the sake of C++ users, heres how to do it using the Berkeley C++ api, which is both undocumented, and has zero examples. It does work pretty well though!.
Create a Dbt (a database Thang, Im not making that up) to keep hold of a memory buffer:
void* buf = new unsigned char[bufferSize];
dbt = new Dbt;
dbt->set_data(buf);
dbt->set_ulen(bufferSize);
dbt->set_flags(DB_DBT_USERMEM);
Associate that with a DBMultipleKeyDataBuilder:
DBMultipleKeyDataBuilder* dbi=new DBMultipleKeyDataBuilder(dbt);
Append your Key and Value pairs one at a time until done or buffer full
dbi->append(curKeyBuf,curKeyLen,curDataBuf,curDataLen);
...(lots more of these)...
USe your DB* db, and a transaction if you wish in txn, and bulk write:
db->put(txn, dbt, NULL, DB_MULTIPLE_KEY );
delete dbi;
I've missed lots of detail, such as checking the buffer is full, or big enough to hold even one KV pair.
A DBMultipleKeyDataBuilder can only be used once, but a really efficient implementation will keep a pool of buffer Dbt objects and reuse them. You can use these Dbts for bulk reading as well, so a common pool of them can be used.