欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C语言编写IDL动态可加载模块(DLM)入门

程序员文章站 2024-03-24 22:22:52
...

由于之前有些工作确实是可以直接从底层对数据进行读写的,如果采用动态链接库的话应该可以提高效率。
参考资料:

HARRIS对于DLM的官方说明
一个第三方的DLM,用于参考学习
另一个讲DLM的CSDN博客,但个人觉得太复杂了
安装路径下该文件夹中所有文件:/idl/external/dlm/*
安装路径下该依赖项头文件:/idl/external/include/idl_export.h

准备文件

  • 模块名.c:假如你的模块名叫mymodule,则mymodule.c即是用于编译的C源码文件。具体见下方讲解。
  • 模块名.def:该文件为/idl/external/dlm/中复件,修改其中第一行为LIBRARY 模块名,第二行为DESCRIPTION '你的描述'即可。
  • 模块名.dlm:该文件为/idl/external/dlm/中复件,用于注册DLM,前五行的参数自己看着格式随便改点就可以,重要的是第六行及之后的文本,具体见下方讲解。
  • 模块名.export:该文件为/idl/external/dlm/中复件,不用改,开袋即食。
  • {build_win.bat | Makefile}:(win平台是bat文件,unix平台是Makefile文件。)该文件为/idl/external/dlm/中复件,用于制作动态链接文件(mymodule.dll/mymodule.so),但这个文件并非通用,需要自己改参数,一是里面的IDL_DIR为安装路径,二是把里面的testmodule替换为你的模块名。

C源码讲解

其实不管是示例的testmodule还是另一篇博客里面都有好些不需要的,我做了很大的精简。
首先要把idl_export.h加进去。

#include <stdio.h>
#include "idl_export.h"

然后是定义自己在IDL中调用的过程或者函数,我定义的是passfn的过程,将字符串参数打印在屏幕上。

static void passfn(int argc, IDL_VPTR argv[]){
	printf("argc: %i\n", argc);
	const char *fn = IDL_VarGetString(argv[0]);
	printf("argv: %s\n", fn);
}

定义过程的格式是(假如你的过程名为pro1)

static void pro1(int argc, IDL_VPTR *argv){
	/*你的功能*/
}

定义函数的格式是(加入你的函数名为func1)

static IDL_VPTR func1(int argc, IDL_VPTR *argv){
	/*你的功能*/
  return wanted;
}

主要说明的是参数传递,argv是从0开始为第一个参数的,即argv[0]并非存储程序的名称。
此外还需要做类型转换:一是传入参数的类型转换,因为传入的参数是头文件idl_export.h中定义的IDL_VPTR类型,所以需要在头文件中大概2000-3000行的位置找到类型转换的函数,比如IDL_VarGetString用于将IDL的string转换为C的char,IDL_DoubleScalar用于将IDL的double转换为C的double。二则是类似的对于返回值的类型转换。
定义完你的函数/过程之后,加上最后一段让IDL载入函数就大功告成了。

int IDL_Load(void){
	static IDL_SYSFUN_DEF2 procedure_addr[] = {
		{ (IDL_FUN_RET) passfn, "PASSFN", 0, IDL_MAX_ARRAY_DIM, 0, 0},
	};
	return IDL_SysRtnAdd(procedure_addr, FALSE, IDL_CARRAY_ELTS(procedure_addr));
}

格式:

//加载函数
static IDL_SYSFUN_DEF2 function_addr[] = {
	{ 函数名, "大写函数名", 最少的参数个数, 最多的参数个数, 这个不知道是啥反正写0就对了, 这个也不知道是啥反正写0就对了},
};
//加载过程
static IDL_SYSFUN_DEF2 procedure_addr[] = {
	{ (IDL_FUN_RET) 过程名, "大写过程名", 最少的参数个数, 最多的参数个数, 这个不知道是啥反正写0就对了, 这个也不知道是啥反正写0就对了},
};

最后的return视情况而定,如果定义了多个过程/函数,则需要用到&&

dlm文件讲解

第六行开始的格式是

FUNCTION 函数名 最少的参数个数 最多的参数个数 {0 | OBSOLETE | KEYWORDS}
PROCEDURE 过程名 最少的参数个数 最多的参数个数 {0 | OBSOLETE | KEYWORDS}

开始使用

  1. make
  2. 打开IDL
  3. DLM_REGISTER, “dlm后缀的完整路径”
  4. DLM_LOAD, “不带路径的模块名”
  5. 使用函数/过程
    C语言编写IDL动态可加载模块(DLM)入门在生成so文件或dll文件前,会先生成机器代码的.o文件,可以删除。另外,DLM_REGISTER是必须的,而DLM_LOAD则不是。如果不想每次调用自己的函数都需要先REGISTER一下,可以把dlm文件和so文件(或者dlm文件和dll文件)拷贝到IDL的!DLM_DIR路径下。
相关标签: IDL