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}
开始使用
- make
- 打开IDL
- DLM_REGISTER, “dlm后缀的完整路径”
- DLM_LOAD, “不带路径的模块名”
- 使用函数/过程
在生成so文件或dll文件前,会先生成机器代码的.o文件,可以删除。另外,DLM_REGISTER是必须的,而DLM_LOAD则不是。如果不想每次调用自己的函数都需要先REGISTER一下,可以把dlm文件和so文件(或者dlm文件和dll文件)拷贝到IDL的!DLM_DIR
路径下。