如果想使用遗留代码传入字符串,因为不能使用char、string类型,故可使用下列方式进行修改:

1、 MystrFcn.c

#include "mex.h"
#include "myStrFun.h"

int myStrFun(char* myStr )
{
    mexPrintf("Param String: %s\n", myStr );
    return 1;
}

2、MystrFcn.h

int myStrFun(char* myStr );

3、 运行这个myStrFcn.m

%%
% This script uses the Legacy code tool to create an in-lined SFunction for
% a user-created function called A2DRead(). 

% create structure def to hold info about this s-function
def = legacy_code('initialize');

%identify the source files.
def.SourceFiles = {'myStrFun.c'};
def.HeaderFiles = {'myStrFun.h'};

% prototype for the function that will be called from the SFunction
% p1 is a parameter that the user specifies through the simulink block
% dialog.  y1 is the output signal for the block.
def.OutputFcnSpec = 'int16 y1 = myStrFun(uint8 p1[])';

% file name that will hold the C source code for the S Function
def.SFunctionName = 'sfun_myStrFun';

% generate the C code for the SFunction and the compile it.
legacy_code('sfcn_cmex_generate', def);
legacy_code('compile', def);

% create a new model with the our newly created Simulink block
legacy_code('slblock_generate', def);

% generate the TLC file that will be used for RTW code generation
legacy_code('sfcn_tlc_generate', def);

% generate the rtwmakecfg.m file used for creating make file for target
legacy_code('rtwmakecfg_generate', def);

% Modifications required to support passing string as a parameter.
% 1. Edit the mask for the block.  Uncheck the Evaluate and Tunable boxes
% for P1.
% 2. Edit sfun_myStrFun.c
%    a. make P1 not tunable:    ssSetSFcnParamTunable(S, 0, 0);
%    b. remove function mdlSetWorkWidths()
%    c. modify the mdlOutputs function.  Replace param code with following:
%       char* cp;
%       const mxArray * param = ssGetSFcnParam(S, 0);               
%       cp = mxArrayToString(param);    /* convert mx array to null terminated string */
%  then...  pass cp to the legacy code function:
%       *y1 = myStrFun( cp);
%
% after you have done all of this, you have to rebuild the mex file:
mex sfun_myStrFun.c myStrFun.c

% Now, run the model.  You should see the text from the block dialog echoed
% to the screen.

4、修改完sfun-mystrfcn.c与模型截图

/**
 * sfun_myStrFun.c
 *
 *    ABSTRACT:
 *      The purpose of this sfunction is to call a simple legacy
 *      function during simulation:
 *
 *         int16 y1 = myStrFun(uint8 p1[])
 *
 *    Simulink version           : 10.6 (R2022b) 13-May-2022
 *    C source code generated on : 10-Sep-2025 08:39:27
 *
 * THIS S-FUNCTION IS GENERATED BY THE LEGACY CODE TOOL AND MAY NOT WORK IF MODIFIED
 */

/**
     %%%-MATLAB_Construction_Commands_Start
     def = legacy_code('initialize');
     def.SFunctionName = 'sfun_myStrFun';
     def.OutputFcnSpec = 'int16 y1 = myStrFun(uint8 p1[])';
     def.HeaderFiles = {'myStrFun.h'};
     def.SourceFiles = {'myStrFun.c'};
     legacy_code('sfcn_cmex_generate', def);
     legacy_code('compile', def);
     %%%-MATLAB_Construction_Commands_End
 */

/* Must specify the S_FUNCTION_NAME as the name of the S-function */
#define S_FUNCTION_NAME  sfun_myStrFun
#define S_FUNCTION_LEVEL 2

/**
 * Need to include simstruc.h for the definition of the SimStruct and
 * its associated macro definitions.
 */
#include "simstruc.h"

/* Specific header file(s) required by the legacy code function */
#include "myStrFun.h"

#define EDIT_OK(S, P_IDX) \
       (!((ssGetSimMode(S)==SS_SIMMODE_SIZES_CALL_ONLY) && mxIsEmpty(ssGetSFcnParam(S, P_IDX))))


#define MDL_CHECK_PARAMETERS
#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
/* Function: mdlCheckParameters ===========================================
 * Abstract:
 *   mdlCheckParameters verifies new parameter settings whenever parameter
 *   change or are re-evaluated during a simulation. When a simulation is
 *   running, changes to S-function parameters can occur at any time during
 *   the simulation loop.
 */
static void mdlCheckParameters(SimStruct *S)
{
    /* Check the parameter 1 */
    if (EDIT_OK(S, 0)) {
        int_T dimsArray[2];
        dimsArray[0] = (int_T)mxGetDimensions(ssGetSFcnParam(S, 0))[0];
        dimsArray[1] = (int_T)mxGetDimensions(ssGetSFcnParam(S, 0))[1];

        /* Parameter 1 must be a vector */
        if ((dimsArray[0] > 1) && (dimsArray[1] > 1)) {
            ssSetErrorStatus(S,"Parameter 1 must be a vector");
            return;
        } /* if */

        /* Check the parameter attributes */
        ssCheckSFcnParamValueAttribs(S, 0, "P1", DYNAMICALLY_TYPED, 2, dimsArray, 0);
    } /* if */

}
#endif

#define MDL_PROCESS_PARAMETERS
#if defined(MDL_PROCESS_PARAMETERS) && defined(MATLAB_MEX_FILE)
/* Function: mdlProcessParameters =========================================
 * Abstract:
 *   Update run-time parameters.
 */
static void mdlProcessParameters(SimStruct *S)
{
    ssUpdateAllTunableParamsAsRunTimeParams(S);
}
#endif

/* Function: mdlInitializeSizes ===========================================
 * Abstract:
 *   The sizes information is used by Simulink to determine the S-function
 *   block's characteristics (number of inputs, outputs, states, etc.).
 */
static void mdlInitializeSizes(SimStruct *S)
{
    /* Number of expected parameters */
    ssSetNumSFcnParams(S, 1);


    #if defined(MATLAB_MEX_FILE) 
    if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {
        /**
         * If the number of expected input parameters is not equal
         * to the number of parameters entered in the dialog box return.
         * Simulink will generate an error indicating that there is a
         * parameter mismatch.
         */
        mdlCheckParameters(S);
        if (ssGetErrorStatus(S) != NULL) return;
    } else {
        /* Return if number of expected != number of actual parameters */
        return;
    } /* if */
    #endif 

    /* Set the parameter's tunability */
//     ssSetSFcnParamTunable(S, 0, 1);
    ssSetSFcnParamTunable(S, 0, 0);

    /* Set the number of work vectors */
    if (!ssSetNumDWork(S, 0)) return;
    ssSetNumPWork(S, 0);

    /* Set the number of input ports */
    if (!ssSetNumInputPorts(S, 0)) return;

    /* Set the number of output ports */
    if (!ssSetNumOutputPorts(S, 1)) return;

    /* Configure the output port 1 */
    ssSetOutputPortDataType(S, 0, SS_INT16);
    {
        int_T y1Width = 1;
        ssSetOutputPortWidth(S, 0, y1Width);
    }
    ssSetOutputPortComplexSignal(S, 0, COMPLEX_NO);
    ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
    ssSetOutputPortOutputExprInRTW(S, 0, 1);
    ssSetOutputPortDimensionsMode(S, 0, FIXED_DIMS_MODE);

    /* Register reserved identifiers to avoid name conflict */
    if (ssRTWGenIsCodeGen(S) || ssGetSimMode(S)==SS_SIMMODE_EXTERNAL) {

        /* Register reserved identifier for  */
        ssRegMdlInfo(S, "myStrFun", MDL_INFO_ID_RESERVED, 0, 0, ssGetPath(S));
    } /* if */

    /* This S-function can be used in referenced model simulating in normal mode */
    ssSetModelReferenceNormalModeSupport(S, MDL_START_AND_MDL_PROCESS_PARAMS_OK);

    /* Set the number of sample time */
    ssSetNumSampleTimes(S, 1);

    /* Set the compliance for the operating point save/restore. */
    ssSetOperatingPointCompliance(S, USE_DEFAULT_OPERATING_POINT);

    ssSetArrayLayoutForCodeGen(S, SS_ALL);

    /* Set the Simulink version this S-Function has been generated in */
    ssSetSimulinkVersionGeneratedIn(S, "10.6");

    /**
     * All options have the form SS_OPTION_<name> and are documented in
     * matlabroot/simulink/include/simstruc.h. The options should be
     * bitwise or'd together as in
     *    ssSetOptions(S, (SS_OPTION_name1 | SS_OPTION_name2))
     */
    ssSetOptions(S,
        SS_OPTION_USE_TLC_WITH_ACCELERATOR |
        SS_OPTION_CAN_BE_CALLED_CONDITIONALLY |
        SS_OPTION_EXCEPTION_FREE_CODE |
        SS_OPTION_WORKS_WITH_CODE_REUSE |
        SS_OPTION_SFUNCTION_INLINED_FOR_RTW |
        SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME
    );
}

/* Function: mdlInitializeSampleTimes =====================================
 * Abstract:
 *   This function is used to specify the sample time(s) for your
 *   S-function. You must register the same number of sample times as
 *   specified in ssSetNumSampleTimes.
 */
static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, FIXED_IN_MINOR_STEP_OFFSET);


    #if defined(ssSetModelReferenceSampleTimeDefaultInheritance)
    ssSetModelReferenceSampleTimeDefaultInheritance(S);
    #endif
}

#define MDL_SET_WORK_WIDTHS
#if defined(MDL_SET_WORK_WIDTHS) && defined(MATLAB_MEX_FILE)
/* Function: mdlSetWorkWidths =============================================
 * Abstract:
 *   The optional method, mdlSetWorkWidths is called after input port
 *   width, output port width, and sample times of the S-function have
 *   been determined to set any state and work vector sizes which are
 *   a function of the input, output, and/or sample times. 
 *   Run-time parameters are registered in this method using methods 
 *   ssSetNumRunTimeParams, ssSetRunTimeParamInfo, and related methods.
 */

static void mdlSetWorkWidths(SimStruct *S)
{
//     /* Set number of run-time parameters */
//     if (!ssSetNumRunTimeParams(S, 1)) return;
// 
//     /* Register the run-time parameter 1 */
//     ssRegDlgParamAsRunTimeParam(S, 0, 0, "p1", ssGetDataTypeId(S, "uint8"));
}
#endif

/* Function: mdlOutputs ===================================================
 * Abstract:
 *   In this function, you compute the outputs of your S-function
 *   block. Generally outputs are placed in the output vector(s),
 *   ssGetOutputPortSignal.
 */
static void mdlOutputs(SimStruct *S, int_T tid)
{
    char* cp;
    const mxArray * param = ssGetSFcnParam(S, 0);               
    cp = mxArrayToString(param);    /* convert mx array to null terminated string */


    /* Get access to Parameter/Input/Output/DWork data */
    int16_T* y1 = (int16_T*) ssGetOutputPortSignal(S, 0);
//     uint8_T* p1 = (uint8_T*) ssGetRunTimeParamInfo(S, 0)->data;


    /* Call the legacy code function */
//     *y1 = myStrFun(p1);
    *y1 = myStrFun(cp);
}

/* Function: mdlTerminate =================================================
 * Abstract:
 *   In this function, you should perform any actions that are necessary
 *   at the termination of a simulation.
 */
static void mdlTerminate(SimStruct *S)
{
}

/* Required S-function trailer */
#ifdef    MATLAB_MEX_FILE
# include "simulink.c"
#else
# include "cg_sfun.h"
#endif

5、 输入命令>> mex sfun_myStrFun.c myStrFun.c

6、 导入sfun_myStrFun.mexw64 运行完,结果如下所示:

更多推荐