Tcl是一个比较简洁的脚本语言,官方地址 http://www.tcl.tk.

tcl脚本加载C实现的动态库非常方便。

1. 为Tcl编写一个用C实现的扩展函数。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tcl.h> extern "C" {
// extern for C++.
int Myimpltcl_Init(Tcl_Interp *Interp);
int Myimpltcl_Unload(Tcl_Interp *Interp);
} int Action_FuncA(int notUsed, Tcl_Interp *interp, int argc, char **argv) {
if (argc != 3) {
// check args, same as main function args.
Tcl_SetResult(interp, "Usage::Action_FuncA arg1 arg2",
TCL_VOLATILE);
return TCL_ERROR;
}
printf("argv[1] is %s.\n", argv[1]);
printf("argv[2] is %s.\n", argv[2]);
// return string.
Tcl_SetResult(interp, "return of Action_FuncA", TCL_VOLATILE);
return TCL_OK;
} int Action_FuncB(int notUsed, Tcl_Interp *interp, int argc, char **argv) {
if (argc != 2) {
// check args, same as main function args.
Tcl_SetResult(interp, "Usage::Action_FuncB arg1",
TCL_VOLATILE);
return TCL_ERROR;
}
printf("argv[1] is %s.\n", argv[1]);
// return string.
Tcl_SetResult(interp, "return of Action_FuncB", TCL_VOLATILE);
return TCL_OK;
} int Myimpltcl_Init(Tcl_Interp *Interp) {
// initialize operation.
Tcl_CreateCommand (Interp, "Action_FuncA", (Tcl_CmdProc *)Action_FuncA, 0, 0);
Tcl_CreateCommand (Interp, "Action_FuncB", (Tcl_CmdProc *)Action_FuncB, 0, 0);
return TCL_OK;
} int Myimpltcl_Unload(Tcl_Interp *Interp, int flags) {
// destroy operation.
return TCL_OK;
}

分析:

tcl.h是加载tcl需要头文件。

初始化函数 Myimpltcl_Init

  使用Tcl_CreateCommand函数创建一个可以在tcl脚本中调用的函数,函数的实现指向C实现的函数。

创建方法 Tcl中可以调用的函数名称 C中实现的函数名称
Tcl_CreateCommand 
Action_FuncA
int Action_FuncA(int notUsed, Tcl_Interp *interp, int argc, char **argv)
Tcl_CreateCommand 
Action_FuncB
int Action_FuncB(int notUsed, Tcl_Interp *interp, int argc, char **argv)

退出函数 Myimpltcl_Unload

  tcl卸载动态库时会调用的函数,用于是否内存和其他的资源。

2. 编写Makefile文件

CC = gcc -g -O3 -w
SHARED_FLAG = -fPIC -shared
PROJECT = libmyimpltcl.so INC = -I./
INC += -I$(TCL_HOME)/include
LIB = -L$(TCL_HOME)/lib -ltcl8.5 all : $(PROJECT) $(PROJECT) :
$(CC) myimpltcl.cpp ${SHARED_FLAG} -o $(PROJECT) $(INC) $(LIB) clean:
rm -rf *.o *.a *.so

分析:

生成的动态库名称必须是libmyimpltcl.so,为什么呢?

Tcl加载C编写的so库的规则是。

void *handle = dlopen("libmyimpltcl.so", RTLD_NOW | RTLD_GLOBAL);

将so库的名称去掉lib前缀

libmyimpltcl.so

把去掉前缀的第一个字母变成大写并增加后缀_Init

myimpltcl --> Myimpltcl_Init

拼接成新的字符串作用动态库的入库函数,用dlsym系统调用得到so中的C函数地址,并执行

dlsym(handle, "Myimpltcl_Init");

3. 测试

[user@host tcl]# tclsh
% load libmyimpltcl.so
% # 加载编译好的so库
% info loaded
% # 查看加载过的库信息
{libmyimpltcl.so Myimpltcl}
% set ret [Action_FuncA param1 param2]
% # 调用so中的C函数Action_FuncA
argv[1] is param1.
argv[2] is param2.
return of Action_FuncA
% puts $ret
return of Action_FuncA
% set retB [Action_FuncB 123]
% # 调用so中的C函数Action_FuncB
argv[1] is 123.
return of Action_FuncB
% puts $retB
return of Action_FuncB

  

Done.

最新文章

  1. ahk之路:利用ahk在window7下实现窗口置顶
  2. Kindle DXG和Win10 64bits无法连接的问题
  3. openstack数据库获取一个虚机的floating_ip, fix_ip, project_name, user_name, hostname, host
  4. lecture11-hopfiled网络与玻尔兹曼机
  5. Python 入门指南
  6. IrregularGridCollectionView处理不定宽度的标签cell
  7. HTML要点(五)&lt;iframe&gt;标签
  8. c#序列化反序列化工具(json,binary,xml)
  9. MVC-生成验证码
  10. ifconfig 源码
  11. javaWeb2之Jsp
  12. 关于 layer.mask = label.layer 出现空白情况
  13. 有了这8款Mac安全杀毒和流氓防护软件,让你的mac清理优化,更加安全
  14. Atitit 酷奇的押金危机 遇到资金链断裂作为创始人应该怎么办
  15. SQL 两个时间获取相差秒数
  16. Python如何操作redis
  17. flask_admin 笔记三 客户化视图
  18. Flash打开新窗口 被浏览器拦截问题 navigateToURL被拦截 真正试验结果
  19. (数据科学学习手札51)用pymysql来操控MySQL数据库
  20. intellij 无法导入 SimpleTagSupport问题

热门文章

  1. 科学计算器(JAVA实现)
  2. weka
  3. Java 读写文件方案
  4. HIbernate二级缓存
  5. 前端之html
  6. JSPatch
  7. 银行卡BIN: Bank Identification Number
  8. MBR与GPT
  9. 发布一个免费开源软件-- PAD流程图绘制软件PADFlowChart
  10. 【LeetCode】241. Different Ways to Add Parentheses