(笔记)Simulink生成动态链接库并使用

前段时间完成了一次生成动态链接库并使用,没有做记录,结果又花了两天重新探索过程,及时记录非常有必要。

使用软件版本:matlab R2017a&R2017b , vs 2013 & vs2015。
完整的测试文件我已经发布至这里,可以免积分下载(该文件使用了R2017a)。

1.新建simulink模型,如下图所示。
(笔记)Simulink生成动态链接库并使用_第1张图片

2.配置仿真条件。
(笔记)Simulink生成动态链接库并使用_第2张图片

(笔记)Simulink生成动态链接库并使用_第3张图片3 . 编译生成C代码
(笔记)Simulink生成动态链接库并使用_第4张图片

(笔记)Simulink生成动态链接库并使用_第5张图片

4. 编译生成动态链接库文件
(笔记)Simulink生成动态链接库并使用_第6张图片上一级目录(与你的simulink模型同级的目录)得到
在这里插入图片描述

这里还有另外一种方法就是用nmake 编译其中的matlab_sourcecode.mk(makefile文件),这种方法会生成完整的*.exe可执行文件,找到其中的上图三个文件拷贝出来,一样可以使用。

5.使用动态链接库文件。
然后就可以在新的程序当中引用动态链接库了,比如我重新在matlab中使用该动态链接库:
用c写S-function :testsfun.c,然后执行mex testsfun.c 编译一次,就可以使用了。

(笔记)Simulink生成动态链接库并使用_第7张图片以下为原simulink模型与动态链接库运行的结果对比,可以看到两个完全一致。
(笔记)Simulink生成动态链接库并使用_第8张图片

遇到的问题:不知道为什么,我第一次新建的simulink文件生成的代码始终有问题,我查看了生成的文件,在生成文件类型和内部变量的命名上都会有差异。生成dll没有问题,但是在使用时,每次运行都会导致软甲崩溃,必须重启才能使用。下边将部分差别标出来。
(笔记)Simulink生成动态链接库并使用_第9张图片7.引用动态链接库所使用的文件testsfun.c & rtwdemo.h

 /*  File    : testsfun.c
 *  Abstract:
 *
 *      A one integration-step delay and hold "memory" function.
 *
 *      Syntax:  [sys, x0] = sfunmem(t,x,u,flag)
 *
 *      This file is designed to be used in a Simulink S-Function block.
 *      It performs a one integration-step delay and hold "memory" function.
 *      Thus, no matter how large or small the last time increment was in
 *      the integration process, this function will hold the input variable
 *      from the last integration step.
 *
 *      Use this function with a clock as input to get the step-size at each
 *      step of a simulation.
 *
 *      This function is similar to the built-in "Memory" block.
 *
 *  Copyright 1990-2013 The MathWorks, Inc.
 */

#define S_FUNCTION_NAME testsfun
#define S_FUNCTION_LEVEL 2

#include 
#include "simstruc.h"
#include 

#define GETSYMBOLADDR GetProcAddress
#define LOADLIB LoadLibrary
#define CLOSELIB FreeLibrary

#define U(element) (*uPtrs[element])  /* Pointer to Input Port0 */

#include "rtwdemo.h"

int32_T i;
void* handleLib;
void (*mdl_initialize)(boolean_T);
void (*mdl_step)(void);
void (*mdl_terminate)(void);
uint8_T (*sum_outptr);
ExternalInputs_test (*mdl_Uptr);
ExternalOutputs_test (*mdl_Yptr);



/*====================*
 * S-function methods *
 *====================*/

/* Function: mdlInitializeSizes ===============================================
 * Abstract:
 *    Call mdlCheckParameters to verify that the parameters are okay,
 *    then setup sizes of the various vectors.
 */
static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S, 0);  /* Number of expected parameters */
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
        return; /* Parameter mismatch will be reported by Simulink */
    }
    
    

	
    handleLib = LOADLIB("./matlab_sourcecode_win64.dll");
    if (!handleLib) {
        printf("Cannot open the specified shared library.\n");
        return(-1);
    }
    
    ssSetNumContStates(S, 0);
    ssSetNumDiscStates(S, 0);

    if (!ssSetNumInputPorts(S, 2)) return;
    ssSetInputPortWidth (S, 0, 1);
    ssSetInputPortWidth (S, 1, 1);
    ssSetInputPortDirectFeedThrough(S, 0, 1);

    if (!ssSetNumOutputPorts(S, 1)) return;
    ssSetOutputPortWidth(S, 0, 1);

    ssSetNumSampleTimes(S, 1);
    ssSetNumRWork(S, 0);
    ssSetNumIWork(S, 0);
    ssSetNumPWork(S, 0);
    ssSetNumModes(S, 0);
    ssSetNumNonsampledZCs(S, 0);
    ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);

    ssSetOptions(S,
                 SS_OPTION_WORKS_WITH_CODE_REUSE |
                 SS_OPTION_EXCEPTION_FREE_CODE |
                 SS_OPTION_USE_TLC_WITH_ACCELERATOR);
    
    #if (defined(LCCDLL)||defined(BORLANDCDLL))
    /* Exported symbols contain leading underscores when DLL is linked with LCC or BORLANDC */
        mdl_initialize =(void(*)(boolean_T))GETSYMBOLADDR(handleLib , "_matlab_sourcecode_initialize");
        mdl_step       =(void(*)(void))GETSYMBOLADDR(handleLib , "_matlab_sourcecode_step");
//         mdl_terminate  =(void(*)(void))GETSYMBOLADDR(handleLib , "_matlab_sourcecode_terminate");
        mdl_Uptr       =(ExternalInputs_test*)GETSYMBOLADDR(handleLib , "_matlab_sourcecode_U");
        mdl_Yptr       =(ExternalOutputs_test*)GETSYMBOLADDR(handleLib , "_matlab_sourcecode_Y");
//         sum_outptr     =(uint8_T*)GETSYMBOLADDR(handleLib , "_sum_out");
    #else	
        mdl_initialize =(void(*)(boolean_T))GETSYMBOLADDR(handleLib , "matlab_sourcecode_initialize");
        mdl_step       =(void(*)(void))GETSYMBOLADDR(handleLib , "matlab_sourcecode_step");
//         mdl_terminate  =(void(*)(void))GETSYMBOLADDR(handleLib , "matlab_sourcecode_terminate");
        mdl_Uptr       =(ExternalInputs_test*)GETSYMBOLADDR(handleLib , "matlab_sourcecode_U");
        mdl_Yptr       =(ExternalOutputs_test*)GETSYMBOLADDR(handleLib , "matlab_sourcecode_Y");
//         sum_outptr     =(uint8_T*)GETSYMBOLADDR(handleLib , "sum_out");
    #endif
        
         mdl_initialize(1);
}


/* Function: mdlInitializeSampleTimes =========================================
 * Abstract:
 *    S-function is continuous, fixed in minor time steps.
 */
static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, FIXED_IN_MINOR_STEP_OFFSET);
    ssSetModelReferenceSampleTimeDefaultInheritance(S);
}



#define MDL_INITIALIZE_CONDITIONS
/* Function: mdlInitializeConditions ========================================
 * Abstract:
 *    The memory state is stored in the RWork vector, initialize it to zero
 */
static void mdlInitializeConditions(SimStruct *S)
{
//     real_T *rwork = ssGetRWork(S);
//     int_T  i;
//  
//     for (i = 0; i < ssGetNumRWork(S); i++) {
//         rwork[i] = 0.0;
//     }
}
 
 

/* Function: mdlOutputs =======================================================
 * Abstract:
 *
 *      y = rwork
 */
static void mdlOutputs(SimStruct *S, int_T tid)
{
    real_T           *y    =  ssGetOutputPortRealSignal(S,0); 
    InputRealPtrsType uPtrs         = ssGetInputPortRealSignalPtrs(S,0);
    const real_T      *u1           = &U(0);
    const real_T      *u2           = &U(1);
    
  
//     UNUSED_ARG(tid); /* not used in single tasking mode */
    
     mdl_Uptr->shuru1 =*u1;
     mdl_Uptr->shuru2 =*u2;
     mdl_step();    
     *y = mdl_Yptr->Output;     
}



#define MDL_UPDATE
/* Function: mdlUpdate ========================================================
 * Abstract:
 *    This function is called once for every major integration time step.
 *    Discrete states are typically updated here, but this function is useful
 *    for performing any tasks that should only take place once per integration
 *    step.
 */
static void mdlUpdate(SimStruct *S, int_T tid)
{
    InputRealPtrsType uPtrs  = ssGetInputPortRealSignalPtrs(S,0);
    real_T            *rwork = ssGetRWork(S);
    int_T             i;
//     real_T           *y    = ssGetOutputPortRealSignal(S,0);

    
//     UNUSED_ARG(tid); /* not used in single tasking mode */
//     mdl_step();
//     *y =10;
}



/* Function: mdlTerminate =====================================================
 * Abstract:
 *    No termination needed, but we are required to have this routine.
 */
static void mdlTerminate(SimStruct *S)
{
    UNUSED_ARG(S); /* unused input argument */
//     mdl_terminate();
}

#if defined(MATLAB_MEX_FILE)
#define MDL_RTW
/* Function: mdlRTW ===========================================================
 * Abstract:
 *    It registers the name "InputAtLastUpdate" for the RWork vector.
 */
static void mdlRTW(SimStruct *S)
{
    if (!ssWriteRTWWorkVect(S, "RWork", 1 /* nNames */,
                            "InputAtLastUpdate", ssGetNumRWork(S))) {
        return;
    }
    /*
      This registration of the symbol "InputAtLastUpdate" allows sfunmem.tlc to
      call LibBlockRWork(InputAtLastUpdate,[...])
     */

}
#endif /* MDL_RTW */

#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

/* File: rtwdemo.h  
 *
 * Abstract:
 *      Header file for example application program to be 
 * used with ERT shared library target demo rtwdemo_shrlib.mdl. 
 *
 * Copyright 2006-2007 The MathWorks, Inc.
 */

#ifndef _APP_MAIN_HEADER_
#define _APP_MAIN_HEADER_

typedef struct {
    real_T shuru1;
    real_T shuru2;
} ExternalInputs_test;

typedef struct {
    real_T Output;
} ExternalOutputs_test;

#endif /*_APP_MAIN_HEADER_*/

/*End of file */

你可能感兴趣的:(编译,动态链接库,simulink)