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

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

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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <tcl.h>
  5.  
  6. extern "C" {
  7. // extern for C++.
  8. int Myimpltcl_Init(Tcl_Interp *Interp);
  9. int Myimpltcl_Unload(Tcl_Interp *Interp);
  10. }
  11.  
  12. int Action_FuncA(int notUsed, Tcl_Interp *interp, int argc, char **argv) {
  13. if (argc != 3) {
  14. // check args, same as main function args.
  15. Tcl_SetResult(interp, "Usage::Action_FuncA arg1 arg2",
  16. TCL_VOLATILE);
  17. return TCL_ERROR;
  18. }
  19. printf("argv[1] is %s.\n", argv[1]);
  20. printf("argv[2] is %s.\n", argv[2]);
  21. // return string.
  22. Tcl_SetResult(interp, "return of Action_FuncA", TCL_VOLATILE);
  23. return TCL_OK;
  24. }
  25.  
  26. int Action_FuncB(int notUsed, Tcl_Interp *interp, int argc, char **argv) {
  27. if (argc != 2) {
  28. // check args, same as main function args.
  29. Tcl_SetResult(interp, "Usage::Action_FuncB arg1",
  30. TCL_VOLATILE);
  31. return TCL_ERROR;
  32. }
  33. printf("argv[1] is %s.\n", argv[1]);
  34. // return string.
  35. Tcl_SetResult(interp, "return of Action_FuncB", TCL_VOLATILE);
  36. return TCL_OK;
  37. }
  38.  
  39. int Myimpltcl_Init(Tcl_Interp *Interp) {
  40. // initialize operation.
  41. Tcl_CreateCommand (Interp, "Action_FuncA", (Tcl_CmdProc *)Action_FuncA, 0, 0);
  42. Tcl_CreateCommand (Interp, "Action_FuncB", (Tcl_CmdProc *)Action_FuncB, 0, 0);
  43. return TCL_OK;
  44. }
  45.  
  46. int Myimpltcl_Unload(Tcl_Interp *Interp, int flags) {
  47. // destroy operation.
  48. return TCL_OK;
  49. }

分析:

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

初始化函数 Myimpltcl_Init

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

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

退出函数 Myimpltcl_Unload

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

2. 编写Makefile文件

  1. CC = gcc -g -O3 -w
  2. SHARED_FLAG = -fPIC -shared
  3. PROJECT = libmyimpltcl.so
  4.  
  5. INC = -I./
  6. INC += -I$(TCL_HOME)/include
  7. LIB = -L$(TCL_HOME)/lib -ltcl8.5
  8.  
  9. all : $(PROJECT)
  10.  
  11. $(PROJECT) :
  12. $(CC) myimpltcl.cpp ${SHARED_FLAG} -o $(PROJECT) $(INC) $(LIB)
  13.  
  14. clean:
  15. 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. 测试

  1. [user@host tcl]# tclsh
  2. % load libmyimpltcl.so
  3. % # 加载编译好的so库
  4. % info loaded
  5. % # 查看加载过的库信息
  6. {libmyimpltcl.so Myimpltcl}
  7. % set ret [Action_FuncA param1 param2]
  8. % # 调用so中的C函数Action_FuncA
  9. argv[1] is param1.
  10. argv[2] is param2.
  11. return of Action_FuncA
  12. % puts $ret
  13. return of Action_FuncA
  14. % set retB [Action_FuncB 123]
  15. % # 调用so中的C函数Action_FuncB
  16. argv[1] is 123.
  17. return of Action_FuncB
  18. % puts $retB
  19. return of Action_FuncB

  

Done.

为Tcl编写C的扩展库的更多相关文章

  1. 如何编写自己的Arduino库?

    一开始写Arduino 的时候很不习惯,没有main函数,因为好多东西都被隐藏了.一直想搞清楚,以便编写自己的库文件.于是研究一下午,下面是一些总结. Arduino工程的初步认识 一.目录规范 当你 ...

  2. PHP扩展编写、PHP扩展调试、VLD源码分析、基于嵌入式Embed SAPI实现opcode查看

    catalogue . 编译PHP源码 . 扩展结构.优缺点 . 使用PHP原生扩展框架wizard ext_skel编写扩展 . 编译安装VLD . Debug调试VLD . VLD源码分析 . 嵌 ...

  3. php笔记08:数据库编程---使用php的MySQL扩展库操作MySQL数据库

    1.使用php的MySQL扩展库操作MySQL数据库: php有3种方式操作MySQL数据库 (1)mysql扩展库 (2)mysqli扩展库 (3)pdo     mysql扩展库与mysql数据库 ...

  4. Python和C++的混合编程(使用Boost编写Python的扩展包)

    想要享受更轻松愉悦的编程,脚本语言是首选.想要更敏捷高效,c++则高山仰止.所以我一直试图在各种通用或者专用的脚本语言中将c++的优势融入其中.原来贡献过一篇<c++和js的混合编程>也是 ...

  5. 『Python CoolBook』C扩展库_其一_用法讲解

    不依靠其他工具,直接使用Python的扩展API来编写一些简单的C扩展模块. 本篇参考PythonCookbook第15节和Python核心编程完成,值得注意的是,Python2.X和Python3. ...

  6. JavaScript学习总结(十四)——JavaScript编写类的扩展方法

    在​J​a​v​a​S​c​r​i​p​t​中​可以使​用​类的p​r​o​t​o​t​y​p​e属性来​扩​展​类的属​性​和​方​法,在实际开发当中,当JavaScript内置的那些类所提供的动态 ...

  7. 使用php的mysqli扩展库操作mysql数据库

    简单介绍mysqli: 1.mysqli(mysql improve mysql扩展库的增强版) mysql扩展库和mysqli扩展库的区别 1.mysqli的稳定性  安全性 和 执行效率有所提高 ...

  8. scrapy进阶-编写中间件和扩展

    中间件: 主要讨论的是下载中间件,明确一下顺序: download_middlewares   -->   server.url    --->  spider_middleware 我主 ...

  9. php数据库编程---mysqli扩展库

    1,mysqli扩展库允许我们访问MySQL数据库,并对MySql数据库进行curd操作.Mysqli扩展库比mysql扩展库加强了. 2,mysqli扩展库和mysql扩展库的比较 (1) mysq ...

随机推荐

  1. 【读书笔记《Bootstrap 实战》】4.企业网站

    上一章有对个人作品站点进行一些优化.本章,轮到我们充实这个作品站点了,补充一些项目,从而展示我们的能力.换句话说,我们要构建一个相对复杂的企业网站主页. 下面有几个成功企业的网站: □ Zappos ...

  2. Qt 之 饼图

    Qt 库由许多模块组成,其中的 Qt Charts,包含了一系列图表组件. 1  饼图 (pie chart) 1.1  Charts 模块 .pro 中添加如下语句: QT += charts 头文 ...

  3. u3d_Shader_effects笔记6 第二章 animating sprite

    1.前面的心情 上班看shader我也是醉了.写完这篇看代码去了,不过看着看着恐怕就会困.... 还有就是上天,我该怎么做,下一步,大懒: 2.参考源头 http://blog.csdn.net/ca ...

  4. IP地址查询接口及调用方法

    1.查询地址 搜狐IP地址查询接口(IP):http://pv.sohu.com/cityjson 1616 IP地址查询接口(IP+地址):http://w.1616.net/chaxun/ipto ...

  5. 第一个Android应用--签证无忧 上线

    用了大概1个多星期的时间,把一个简单的应用完成,[签证无忧]是基于在我所在公司办理签证的前提下,为方便客户查询进度所开发,后来我加了淘宝的购买链接,这样客人在以后需要时不需要到淘宝查找了. 签证无忧这 ...

  6. 在oracle中,如何当前系统时间往前推7天

    ' day from dual 另附: 当前时间减去7分钟的时间 ' MINUTE from dual 当前时间减去7小时的时间 ' hour from dual 当前时间减去7天的时间 ' day ...

  7. 79 umount-卸除目前挂在Linux目录中的文件系统

    Linux umount命令用于卸除文件系统. umount可卸除目前挂在Linux目录中的文件系统. 语法 umount [-ahnrvV][-t <文件系统类型>][文件系统] 参数: ...

  8. Android Hook 借助Xposed

    主要就是使用到了Xposed中的两个比较重要的方法,handleLoadPackage获取包加载时候的回调并拿到其对应的classLoader:findAndHookMethod对指定类的方法进行Ho ...

  9. 剑指offer 面试题64 数据流的中位数

    struct cmp { bool operator()(double a, double b) { return a > b; } }; class Solution { public: vo ...

  10. UIDynamic(简单介绍)

    一.简单介绍 1.什么是UIDynamic UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象 如:重力.弹性碰撞等现 ...