Playing around with it a bit, I came up with a fairly messy way to imlement this by passing a pointer to the pwork vector in the model outputs function. It seems like there must be a safer solution in Simulink though...
#define S_FUNCTION_NAME  sfun_RandomStream
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
#include <random>
#include "RandomNumberStream.h"
enum params {SEED_idx, NPARAMS};
enum outputs {STREAMPTR_idx, NOUT};
static int tmp = 0;
static void mdlInitializeSizes(SimStruct *S)
{
    int_T   status;
    DTypeId  id;
    tmp = 0;
    ssSetNumSFcnParams(S, params::NPARAMS); //seed
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
        return; /* Parameter mismatch will be reported by Simulink */
    }
    if (!ssSetNumInputPorts(S, 0)) return;
    if (!ssSetNumOutputPorts(S,outputs::NOUT)) return;
    ssSetOutputPortWidth(S, outputs::STREAMPTR_idx, 1);
    id = ssRegisterDataType(S, "voidPtr");
    if(id == INVALID_DTYPE_ID) return;
    status = ssSetDataTypeSize(S, id, sizeof(voidPtr));
    if(status == 0) return;
    ssSetOutputPortDataType(S, outputs::STREAMPTR_idx, id);
    ssSetNumSampleTimes(S, 1);    
    ssSetNumPWork(S,1);
    ssSetOperatingPointCompliance(S, USE_DEFAULT_OPERATING_POINT);
    ssSetOptions(S,
                 SS_OPTION_WORKS_WITH_CODE_REUSE |
                 SS_OPTION_EXCEPTION_FREE_CODE);
}
#define MDL_START
static void mdlStart(SimStruct *S)
{
    double seed = (double) mxGetScalar(ssGetSFcnParam(S, SEED_idx));
    //printf("SEED: %i\n", seed);
    RandomGenerator *generator = new RandomGenerator(seed);
    (ssGetPWork(S))[0] = (void *)(generator);
}
static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, 0.0);
    ssSetModelReferenceSampleTimeDefaultInheritance(S); 
}
static void mdlOutputs(SimStruct *S, int_T tid)
{
    voidPtr pwork = ssGetPWork(S)[0];
    voidPtr *out = (voidPtr *)ssGetOutputPortSignal(S, 0);
    //void *tmp = (void *) out[0];
    out[0] = pwork;
     //   printf("randStream mdlOutputs address: %p\n", out[0]);
}
static void mdlTerminate(SimStruct *S)
{
    delete ( RandomGenerator *)ssGetPWorkValue(S,0);
}
#ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
#include "simulink.c"      /* MEX-file interface mechanism */
#else
#include "cg_sfun.h"       /* Code generation registration function */
#endif
%implements "sfun_RandomStream" "C"
%function BlockTypeSetup(block, system) void
    %% The Target Language must be C
    %if ::GenCPP!=1 && !IsModelReferenceSimTarget()
        %<LibReportFatalError("Random Number Generator must be implemented in c++.")>
    %endif
 %<LibAddToCommonIncludes("RandomNumberStream.h")>
%endfunction %% BlockTypeSetup
%function Start(block, system) Output
  /* %<Type> Block: %<Name> */
  %assign seed = LibBlockParameterValue(block.Parameter[0], 0)
  RandomGenerator *stream  = new RandomGenerator((double) %<seed>);
  %<LibBlockPWork(0, "", "", 0)> = stream;
%endfunction
%function Outputs(block, system) Output
  /* %<Type> Block: %<Name> */
  %assign pwork = LibBlockPWork(0, "", "", 0)
  %assign out     = LibBlockOutputSignal(0, "", "", 0)
  %<out> = %<pwork>;
%endfunction
%function Terminate(block, system) Output
  %switch SFunctionType
    %case "TLC"
      /* %<Type> Block: %<Name> */
      %assign u = LibBlockPWork(0, "", "", 0)
      RandomGenerator *stream = (RandomGenerator *)%<u>;
      delete stream;
      %break
  %endswitch
%endfunction
#define S_FUNCTION_NAME  sfun_NormalDist
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
#include <random>
#include "RandomNumberStream.h"
enum params {TS_idx, SIGMA_idx, MU_idx, NPARAMS};
enum outputs {VAL_idx, NOUT};
enum inputs  {STREAM_idx, NINP};
static void mdlInitializeSizes(SimStruct *S)
{
    int_T   status;
    DTypeId  id;
    ssSetNumSFcnParams(S, params::NPARAMS);  /* Number of expected parameters */
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {return; }
    ssSetNumContStates(S, 0);
    ssSetNumDiscStates(S, 0);
    if (!ssSetNumInputPorts(S, inputs::NINP)) return;
    ssSetInputPortWidth(S, inputs::STREAM_idx, 1);
    //DTypeId id = ssGetDataTypeId(S, "voidPtr");
    id = ssRegisterDataType(S, "voidPtr");
    if(id == INVALID_DTYPE_ID) return;
    status = ssSetDataTypeSize(S, id, sizeof(voidPtr));
    if(status == 0) return;
    if(id != ssSetInputPortDataType(S, inputs::STREAM_idx, id)) return;
    ssSetInputPortDirectFeedThrough(S, inputs::STREAM_idx, 1);
    if (!ssSetNumOutputPorts(S, outputs::NOUT)) return;
    ssSetOutputPortWidth(S, outputs::VAL_idx, 1);
    ssSetNumSampleTimes(S, 1);
    ssSetNumRWork(S, 0);
    ssSetNumIWork(S, 0);
    ssSetNumPWork(S, 0);
    ssSetNumModes(S, 0);
    ssSetNumNonsampledZCs(S, 0);
    ssSetOperatingPointCompliance(S, USE_DEFAULT_OPERATING_POINT);
    //ssSetRuntimeThreadSafetyCompliance(S, RUNTIME_THREAD_SAFETY_COMPLIANCE_TRUE);
    //ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
    ssSupportsMultipleExecInstances(S, true);
}
static void mdlInitializeSampleTimes(SimStruct *S)
{
    double ts = (double) mxGetScalar(ssGetSFcnParam(S, TS_idx));
    ssSetSampleTime(S, 0, ts);
    ssSetOffsetTime(S, 0, 0.0);
}
static void mdlOutputs(SimStruct *S, int_T tid)
{
    voidPtr **inPtr = ((voidPtr**) ssGetInputPortSignal(S, inputs::STREAM_idx));
    if(inPtr == NULL)
        return;
    voidPtr in = inPtr[0][0];
    RandomGenerator *engine = static_cast<RandomGenerator*>(in);
    if(engine == NULL) //deal with sample time issues...
        return;
    double sigma = (double) mxGetScalar(ssGetSFcnParam(S, SIGMA_idx));
    double mu = (double) mxGetScalar(ssGetSFcnParam(S, MU_idx));
    std::normal_distribution<double> distribution(mu, sigma);
    double val = distribution(engine->getEngine());
    double *out =  (double*) ssGetOutputPortSignal(S, outputs::VAL_idx);
    out[0] = val;
}
static void mdlTerminate(SimStruct *S)
{
}
/*=============================*
 * Required S-function trailer *
 *=============================*/
#ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
#include "simulink.c"      /* MEX-file interface mechanism */
#else
#include "cg_sfun.h"       /* Code generation registration function */
#endif
%implements "sfun_NormalDist" "C"
%function BlockTypeSetup(block, system) void
    %% The Target Language must be C
    %if ::GenCPP!=1 && !IsModelReferenceSimTarget()
        %<LibReportFatalError("Random Number Generator must be implemented in c++.")>
    %endif
 %<LibAddToCommonIncludes("RandomNumberStream.h")>
%endfunction %% BlockTypeSetup
%function Outputs(block, system) Output
  /* %<Type> Block: %<Name> */
  %assign pu    = LibBlockInputSignalAddr(0, "", "", 0)
  %assign y     = LibBlockOutputSignal(0, "", "", 0)
  RandomGenerator *engine = (RandomGenerator *)(*%<pu>);
  %assign sigma = LibBlockParameterValue(block.Parameter[1], 0)
  %assign mu = LibBlockParameterValue(block.Parameter[2], 0)
  std::normal_distribution<double> distribution((double) %<mu>, (double) %<sigma>);
  double val = distribution(engine->getEngine());
  %<y> = val;
%endfunction
