Calling C and C++ from IDL (三) ——数组传递

来源:互联网 发布:淘宝套现可靠的店家 编辑:程序博客网 时间:2024/06/15 16:40

在IDL与C/C++混合编程的过程中,经常会遇到数据之间的传递,其中,数组的传递非常普遍。本文将简单介绍如何在IDL与C/C++之间进行数据传递。在上一篇文章中,介绍了变量传递,这里将在此基础上修改部分内容。
第一步:首先在IDLtoC.h文件中添加如下代码:

/*IDLtoCarrayExamples.c*/extern void IDLtoC_arrayExample_exit_handler(void);extern int IDLtoC_arrayExampleStartup(void);

目的是添加启动函数和exit_handler,与上一篇传递变量的作用一致。
第二步:在IDLtoC.c文件中编写如下代码:

if (!IDLtoC_arrayExampleStartup())    {        IDL_MessageFromBlock(msg_block, IDLtoC_ERROR, IDL_MSG_RET, "Unable to initialize C array example");    }

这段代码需要放置在IDL_Load函数中,因为IDL_Load函数是与IDL进行交互的接口。
第三步:新建一个IDLtoCarrayExamples.c文件

#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include "export.h"#include "IDLtoC.h"/*global here*/static char statusBuffer[256];/*函数原型*/extern void IDL_CDECL IDLtoC_arrayInPlace(int argc, IDL_VPTR argv[], char *argk);extern IDL_VPTR IDL_CDECL IDLtoC_singleIntArray(int argc, IDL_VPTR argv[], char *argk);/*define the functions*/static IDL_SYSFUN_DEF2 IDLtoC_functions[]={    {IDLtoC_singleIntArray,"IDLTOC_SINGLEINTARRAY",1,1,0,0},};static IDL_SYSFUN_DEF2 IDLtoC_procedures[]={    { (IDL_FUN_RET)IDLtoC_arrayInPlace, "IDLTOC_ARRAYINPLACE", 1, 1, 0, 0 },};/*check which system we are on*/#ifdef WIN32#include<Windows.h>#endif/*startup call when DLM is loaded*/int IDLtoC_arrayExampleStartup(void){    if (!IDL_SysRtnAdd(IDLtoC_functions, TRUE, ARRLEN(IDLtoC_functions)))    {        return IDL_FALSE;    }    if (!IDL_SysRtnAdd(IDLtoC_procedures, FALSE, ARRLEN(IDLtoC_procedures)))    {        return IDL_FALSE;    }    /*register the exit handler*/    IDL_ExitRegister(IDLtoC_arrayExample_exit_handler);    return (IDL_TRUE);}/*Called when IDL is shutdown*/void IDLtoC_arrayExample_exit_handler(void){    /*nothing special to do in this case*/}IDL_VPTR IDL_CDECL IDLtoC_singleIntArray(int argc, IDL_VPTR argv[], char * argk){    int ndims, numElements, i;    char *pbInArray, *pbOutArray;    short *psInArray, *psOutArray;    int *piInArray, *piOutArray;    float *pfInArray, *pfOutArray;    double *pdInArray, *pdOutArray;    IDL_VPTR ivFloatArray, ivDoubleArray, ivLongArray, ivShortArray, ivByteArray;    IDL_ENSURE_ARRAY(argv[0]);    ndims = argv[0]->value.arr->n_dim;    numElements = argv[0]->value.arr->n_elts;    switch (argv[0]->type)    {    case IDL_TYP_BYTE:        /*create the output array*/        pbOutArray = IDL_MakeTempArray((int)IDL_TYP_BYTE,  ndims, argv[0]->value.arr->dim, IDL_ARR_INI_ZERO, &ivByteArray);        /*Pull out the data from IDL*/        pbInArray = (char*)argv[0]->value.arr->data;        /*send a message back to IDL*/        sprintf(statusBuffer, "You send a byte array");        IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, statusBuffer);        /*change the data a little*/        for (i = 0; i < numElements; i++)        {            pbOutArray[i] = pbInArray[i] + 10;        }        /*return the result*/        return ivByteArray;    case IDL_TYP_INT:        psOutArray = (short*)IDL_MakeTempArray((int)IDL_TYP_INT, ndims, argv[0]->value.arr->dim, IDL_ARR_INI_ZERO, &ivShortArray);        psInArray = (short*)argv[0]->value.arr->data;        sprintf(statusBuffer, "You send an integer array");        IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, statusBuffer);        for (i = 0; i < numElements; i++)        {            psOutArray[i] = psInArray[i] - 25;        }        return ivShortArray;    case IDL_TYP_LONG:        piOutArray = (int*)IDL_MakeTempArray((int)IDL_TYP_LONG, ndims, argv[0]->value.arr->dim, IDL_ARR_INI_ZERO, &ivLongArray);        piInArray = (int*)argv[0]->value.arr->data;        sprintf(statusBuffer, "You send an long array");        IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, statusBuffer);        for (i = 0; i < numElements; i++)        {            piOutArray[i] = piInArray[i] * 2;        }        return ivLongArray;    case IDL_TYP_FLOAT:        pfOutArray = (float*)IDL_MakeTempArray((int)IDL_TYP_FLOAT, ndims, argv[0]->value.arr->dim, IDL_ARR_INI_ZERO, &ivFloatArray);        pfInArray = (float*)argv[0]->value.arr->data;        sprintf(statusBuffer, "You send an float array");        IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, statusBuffer);        for (i = 0; i < numElements; i++)        {            pfOutArray[i] = pfInArray[i] * 2.0;        }        return ivFloatArray;    case IDL_TYP_DOUBLE:        pdOutArray = (double*)IDL_MakeTempArray((int)IDL_TYP_DOUBLE, ndims, argv[0]->value.arr->dim, IDL_ARR_INI_ZERO, &ivDoubleArray);        pfInArray = (double*)argv[0]->value.arr->data;        sprintf(statusBuffer, "You send an integer array");        IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, statusBuffer);        for (i = 0; i < numElements; i++)        {            pdOutArray[i] = pdInArray[i] /2.0;        }        return ivDoubleArray;    case IDL_TYP_STRING:        IDL_MessageFromBlock(msg_block, IDLtoC_NOSTRINGARRAY, IDL_MSG_LONGJMP, "in IDLtoC_singleIntArray()");        break;    default:        sprintf(statusBuffer, "You send an array type that was not modified");        IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, statusBuffer);        return (IDL_GettmpLong(-1));    }}void IDL_CDECL IDLtoC_arrayInPlace(int argc, IDL_VPTR argv[], char *argk){    /*    Called in IDL as         inputArray=intarr(5)        IDLtoC_arrayInPlace,inputArray        print,inputArray        help,inputArray    */    int ndim, numElements, i;    double *pbOutArray;    IDL_VPTR vpTmp;    IDL_EXCLUDE_EXPR(argv[0]);    IDL_ENSURE_ARRAY(argv[0]);    ndim = argv[0]->value.arr->n_dim;    numElements = argv[0]->value.arr->n_elts;    /*convert the array to double*/    vpTmp = IDL_CvtDbl(1, &(argv[0]));    pbOutArray = (double*)vpTmp->value.arr->data;    for (i = 0; i < numElements; i++)    {        pbOutArray[i] = 11.0;    }    if (vpTmp != argv[0])    {        IDL_VarCopy(vpTmp, argv[0]);    }}

第四步:修改DLM文件为:

MODULE IDLtoCDESCRIPTION example programs IDL to CVERSION 1.0SOURCE DuanYaxinBUILD_DATE April 2016FUNCTION IDLTOC_SINGLEINT 1 1FUNCTION IDLTOC_FINALSCALAR 4 4FUNCTION IDLTOC_SINGLEINTARRAY 1 1PROCEDURE IDLTOC_DOUBLEINT 2 2PROCEDURE IDLTOC_ARRAYINPLACE 1 1

第五步:编译,运行。

0 0
原创粉丝点击