What I settled on in the end was a helper class that used the reflection API to parse the vs/ps parameters, and had methods like set_variable(name, value) to set the values (they actually mapped the cbuffer if needed, and updated the memory directly).