matlab使用legacy_code这个函数传参为字符串
·
如果想使用遗留代码传入字符串,因为不能使用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 运行完,结果如下所示:

更多推荐


所有评论(0)