Calling C and C++ from IDL (一)

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 name
DESCRIPTION  description
VERSION version
SOURCE source
BUILD_DATE date
FUNCTION name arg1 arg2
PROCEDURE 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"
EXPORTS
IDL_Load @ 1

步骤7:创建一个DLM文件

MODULE simpleExample
DESCRIPTION very simple Example
VERSION 1.0
SOURCE Duan Yaxin
BUILD_DATE NOVEMBER 2000
FUNCTION SIMPLEFUNCTION 0 0
PROCEDURE SIMPLEPROCEDURE 0 0

步骤8:编译生成dll.

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

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


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





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值