问题描述
我一直在使用CBLOCK4在Scilab / Xcos中开发自己的模块。 该块中的C语言代码如下:
#include <stdio.h>
#include "scicos_block4.h"
#define U ((SCSREAL_cop *)GetRealInPortPtrs(block,1))
#define Y ((SCSREAL_cop *)GetRealOutPortPtrs(block,1))
#define X ((SCSREAL_cop *)GetState(block))
#define dX ((SCSREAL_cop *)GetDerState(block))
#define Xk ((SCSREAL_cop *)GetDstate(block))
#define W ((SCSREAL_cop *)GetWorkPtrs(block))
// parameters
#define N (GetIparPtrs(block)[0])
typedef struct
{
double *buffer;
double *sum;
int *index;
}MovingAverage_t;
FILE *f;
void MovingAverage(scicos_block *block,int flag)
{
MovingAverage_t *ptr;
int bufferPos;
if(flag == 4)
{
/* init */
f = fopen("Debug.txt","w");
if((*(block->work) = (MovingAverage_t *)scicos_malloc(sizeof(MovingAverage_t))) == NULL)
{
set_block_error(-16);
return;
}
ptr = (MovingAverage_t*)*block->work;
fprintf(f,"ptr: %ld \n",ptr);
if((ptr->buffer = (double*)scicos_malloc(sizeof(double)*N)) == NULL)
{
scicos_free(*(block->work));
fclose(f);
set_block_error(-16);
return;
}
if((ptr->sum = (double*)scicos_malloc(sizeof(double))) == NULL)
{
scicos_free(*(ptr->buffer));
scicos_free(*(block->work));
fclose(f);
set_block_error(-16);
return;
}
if((ptr->index = (int*)scicos_malloc(sizeof(int))) == NULL)
{
scicos_free(*(ptr->buffer));
scicos_free(*(ptr->sum));
scicos_free(*(block->work));
fclose(f);
set_block_error(-16);
return;
}
fprintf(f,"ptr->buffer: %ld \n",ptr->buffer);
fprintf(f,"ptr->sum: %ld \n",ptr->sum);
fprintf(f,"ptr->index: %ld \n",ptr->index);
int i;
for(i = 0; i < N; i++)
{
ptr->buffer[i] = 0;
}
*(ptr->sum) = 0;
*(ptr->index) = 0;
for(i = 0; i < N; i++)
{
fprintf(f,"buffer[%d]: %f\n",i,ptr->buffer[i]);
}
fprintf(f,"*(ptr->sum): %f\n",*(ptr->sum));
fprintf(f,"*(ptr->index): %d\n",*(ptr->index));
}
else if(flag == 1)
{
fprintf(f,"In: %f \n",U[0]);
ptr->buffer[0] = U[0];
int i;
for(i = 0; i < N; i++)
{
fprintf(f,ptr->buffer[i]);
}
}
else if (flag == 5)
{
/* ending */
scicos_free(*(block->work));
fclose(f);
}
}
为了完整性,我还附加了scicos_block结构:
typedef struct
{
int nevprt;
voidg funpt;
int type;
int scsptr;
int nz;
double *z;
int noz;
int *ozsz;
int *oztyp;
void **ozptr;
int nx;
double *x;
double *xd;
double *res;
int *xprop;
int nin;
int *insz;
void **inptr;
int nout;
int *outsz;
void **outptr;
int nevout;
double *evout;
int nrpar;
double *rpar;
int nipar;
int *ipar;
int nopar;
int *oparsz;
int *opartyp;
void **oparptr;
int ng;
double *g;
int ztyp;
int *jroot;
char *label;
void **work;
int nmode;
int *mode;
char *uid;
}scicos_block;
我能够成功编译代码,但是如果我运行包含 我的CBLOCK4块我总是收到以下错误消息:
警告!!! Scilab发现严重错误(EXCEPTION_ACCESS_VIOLATION) 具有“ scicosim”功能。 保存数据并重新启动Scilab。
并且模拟也不会开始。我发现,如果我删除了CBLOCK4块中的以下代码行,则模拟开始工作:
ptr->buffer[0] = U[0];
int i;
for(i = 0; i < N; i++)
{
fprintf(f,ptr->buffer[i]);
}
我怀疑我的C代码中是否存在一些错误(可能与内存有关) 分配),但我找不到它。是否有人对Scilab / Xcos有经验 CBLOCK4的用法?
解决方法
我经历过很难在cblock4上获得良好的信息/示例,但是经过大量的搜索之后,我现在将以下内容用于缓冲区实现(采用实数输入,输出N个最后样本的向量):
#include "scicos_block4.h"
#define r_IN(n,i) ((GetRealInPortPtrs(block,n+1))[(i)])
#define r_OUT(n,i) ((GetRealOutPortPtrs(block,n+1))[(i)])
#define in (r_IN(0,0)) // input,single real
#define out(n) (r_OUT(0,n)) // output,vector(1,N) real
#define nSamples (GetOutPortSize(block,1,2))
#define setting0 (GetIparPtrs(block)[0])
#define X (GetState(block)[0]) // state
#define Xdot (GetDerState(block)[0]) // derivative of the state
#define surface0 (GetGPtrs(block)[0])
#define mode0 (GetModePtrs(block)[0])
#define wrk(i) (((double*)GetWorkPtrs(block))[i])
void buffer(scicos_block *block,int flag)
{
int i;
switch(flag){
case 0: // calculate derivative
break;
case 1: // calculate output
for(i=1; i<nSamples; i++) out(i-1)=out(i);
out(nSamples-1)=in;
break;
case 2: // update states
break;
case 3: // event
break;
case 4: // init
break;
case 5: // done,deinit
break;
case 6: // re-initialization
break;
case 9: // calculate surfaces and modes
break;
}
}
注意没有malloc,它只是将输出用作缓冲区...