Calling C and C++ from IDL (一)

来源:互联网 发布:js把URL转换为对象 编辑:程序博客网 时间:2024/06/14 12:01

Calling C and C++ from IDL (一)

奋斗怒了,最近写毕业论文用到了IDL与C++混合编程,刚开始使用IDL自带的命令Call_External调用C++编写的动态链接库DLL,一切都准备就绪,发现在IDL 与C++之间传递数据,特别是一些比较复杂的数据(数组、结构体)时出现了问题。就拿传递数组来说,需要在IDL中为数组开辟内存,但是数组的大小只有在调用完DLL之后才可以确定,之后各种百度,百度不行用谷歌,发现了一本比较有用的书《Calling C from idl》,于是开始阅读这本书的电子版(English)。遂决定一边阅读一边写一些心得体会。

DLM基础

   一个IDL DLM需要两个文件的支持,分别为ASCII模块描述文件(以.dlm扩展名结尾),还有一个就是库文件(DLL)包含被调用的函数代码。在Windows平台下,还需要为链接库指定一个模块定义文件(.def)。

模块描述文件说明

       一个模块描述文件是IDL启动后需要读取的简单文本文件,里面包含了IDL需要加载的例程的相关信息。它的语法规则如下:

MODULE nameDESCRIPTION  descriptionVERSION versionSOURCE sourceBUILD_DATE dateFUNCTION name arg1 arg2PROCEDURE name arg1 arg2

分别表示模块名称、描述、版本、作者、日期、函数名以及最少参数最多参数个数、过程名以及最少参数最多参数个数。

一个简单的例子

开发环境为VS2013 ,操作系统为Windows8.1

步骤1:首先使用VS2013创建一个DLL空项目(此处略去),名称为simpleExample

步骤2:将IDL  ../external目录下的export.h文件以及  ../bin.x86目录下的idl.lib库一起复制到该项目目录下,为连接器配置附加库目录以及附加依赖项,将export.h添加到项目头文件目录中。

步骤3:创建一个头文件simpleExample.h,代码如下:

#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include "export.h"#define ARRLEN(arr) (sizeof(arr)/sizeof(arr[0]))//函数原型extern void IDL_CDECL simpleProcedure(int argc, IDL_VPTR argv[], char* argk);extern IDL_VPTR IDL_CDECL simpleFunction(int argc, IDL_VPTR argv[], char* argk);

这两个函数原型中都包含三个参数,他们分别代表参数个数,指针数组,里面的元素是IDL定义的IDL_VPTR指针,指向参数,argk表示关键字。

步骤4:创建相应的源文件simpleExample.c。代码如下:

#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include "export.h"#include "simpleExample.h"IDL_VPTR IDL_CDECL simpleFunction(int argc, IDL_VPTR argv[], char* argk){ IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, "simpleFunction called");return (IDL_GettmpLong(0));}void IDL_CDECL simpleProcedure(int argc, IDL_VPTR argv[], char* argk){IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, "simpleProcedure called");}

步骤5:创建IDL_Load.c源文件。所有的自定义的库文件中都必须包含一个名为IDL_Load函数,该函数没有参数,返回类型为int ,返回0 表示失败,1表示成功

#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include "export.h"#include "simpleExample.h"int IDL_Load(void){static IDL_SYSFUN_DEF2 procedure_addr[]={{ (IDL_SYSRTN_GENERIC)simpleProcedure,"SIMPLEPROCEDURE",0,0,0,0 },};static IDL_SYSFUN_DEF2 function_addr[]={{ simpleFunction, "SIMPLEFUNCTION",0,0,0,0 },};return IDL_SysRtnAdd(function_addr, IDL_TRUE, ARRLEN(function_addr)) && IDL_SysRtnAdd(procedure_addr, IDL_FALSE, ARRLEN(procedure_addr));}

其中IDL_SYSFUN_DEF2是一个结构体,他的定义为:

typedef struct{IDL_SYSRTN_GENERIC funct_addr;char* name;usigned short arg_min;usigned short arg_max;int flags;void * extra;}IDL_SYSFUN_DEF2

步骤6:创建模块定义文件.def

LIBRARY "simpleExample"EXPORTSIDL_Load @ 1

步骤7:创建一个DLM文件

MODULE simpleExampleDESCRIPTION very simple ExampleVERSION 1.0SOURCE Duan YaxinBUILD_DATE NOVEMBER 2000FUNCTION SIMPLEFUNCTION 0 0PROCEDURE SIMPLEPROCEDURE 0 0

步骤8:编译生成dll.

步骤9:将生成的dll文件和dlm文件复制到IDL安装目录下的 ../bin.x86下。

步骤10:启动IDL,在命令中进行测试:


至此,一个简单的IDL C++混合编程完成。如有漏洞或疏忽的地方欢迎指出。





0 0
原创粉丝点击