Calling C and C++ from IDL (三) ——数组传递
2016-04-11 19:51
741 查看
在IDL与C/C++混合编程的过程中,经常会遇到数据之间的传递,其中,数组的传递非常普遍。本文将简单介绍如何在IDL与C/C++之间进行数据传递。在上一篇文章中,介绍了变量传递,这里将在此基础上修改部分内容。
第一步:首先在IDLtoC.h文件中添加如下代码:
目的是添加启动函数和exit_handler,与上一篇传递变量的作用一致。
第二步:在IDLtoC.c文件中编写如下代码:
这段代码需要放置在IDL_Load函数中,因为IDL_Load函数是与IDL进行交互的接口。
第三步:新建一个IDLtoCarrayExamples.c文件
第四步:修改DLM文件为:
第五步:编译,运行。
第一步:首先在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 IDLtoC DESCRIPTION example programs IDL to C VERSION 1.0 SOURCE DuanYaxin BUILD_DATE April 2016 FUNCTION IDLTOC_SINGLEINT 1 1 FUNCTION IDLTOC_FINALSCALAR 4 4 FUNCTION IDLTOC_SINGLEINTARRAY 1 1 PROCEDURE IDLTOC_DOUBLEINT 2 2 PROCEDURE IDLTOC_ARRAYINPLACE 1 1
第五步:编译,运行。
相关文章推荐
- FlatBuffers要点
- Calling C and C++ from IDL (二)——变量传递
- 如何将IDL转换成EXE(C#)
- IDL编程小技巧
- 将封装了envi功能的IDL类导出成java类,方便java调用
- IDL学习笔记(1)
- IDL与Matlab的比较
- RMI CORBA AIDL IPC RPC 之间的关系
- IDL接口定义语言教程
- FlatBuffers使用记录(Golang)
- 北京市气溶胶在线反演系统V2.0
- COM Sink-Event 实现
- IDL 读取显示HDF文件
- ENVI\IDL 与C# 混编时的问题
- ENVI\IDL 重采样 栅格单元大小设置
- shapefile转换evf 时岛的处理办法
- ENVI 监督分类Max stdev from Mean 参数IDL中的设置
- 关于『百钱买百鸡』问题的一种C++实现
- 工作备忘等
- RPC的实现