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.

为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. 【Python数据分析】Python3多线程并发网络爬虫-以豆瓣图书Top250为例

    基于上两篇文章的工作 [Python数据分析]Python3操作Excel-以豆瓣图书Top250为例 [Python数据分析]Python3操作Excel(二) 一些问题的解决与优化 已经正确地实现 ...

  2. Hibernate注解配置

    在之前的第一次对框架的实际应用中,我使用的是Hibernate的xml配置方法,xml配置方法非常繁琐, 还是推荐所有使用Hibernate的人使用注解方式进行配置,在这篇文章中,我将列举出我们常用的 ...

  3. 玩转Unity资源,对象和序列化(下)

    本文将从Unity编辑器和运行时两个角度出发,主要探讨以下两方面内容:Unity序列化系统内部细节以及Unity如何维护不同对象之间的强引用.另外还会讨论对象与资源的技术实现差别. 译注:除非特别说明 ...

  4. [No000076]用Eclipse编写python(配置PyDev插件)

    下载,安装python解释器 地址:https://www.python.org/downloads/ 下载,安装java jdk 地址:http://www.oracle.com/technetwo ...

  5. 解决 uuid.h找不到的问题

    http://blog.csdn.net/commshare/article/details/40835407

  6. IIS上部署Net.Core

    部署: 1.安装vc_redist.x64vc_redist.x64 2.安装DotNetCore.1.0.0.RC2-WindowsHosting 3.安装DotNetCore.1.0.0-SDK. ...

  7. ZH奶酪:自然语言处理工具LTP语言云调用方法

    前言 LTP语言云平台 不支持离线调用: 支持分词.词性标注.命名实体识别.依存句法分析.语义角色标注: 不支持自定义词表,但是你可以先用其他支持自定义分词的工具(例如中科院的NLPIR)把文本进行分 ...

  8. 秀起来的coding

    转载:http://www.zuidsaima.com/html/1695882735602688/index.html

  9. SharpPcap网络包捕获框架的使用--实例代码在vs2005调试通过

    转自:http://hi.baidu.com/boyxgb/blog/item/89ac86fbdff5f82c4e4aea2e.html 由于项目的需要,要从终端与服务器的通讯数据中获取终端硬件状态 ...

  10. __ block

    1.__block对象在block中是可以被修改.重新赋值的. 2.__block对象在block中不会被block强引用一次,从而不会出现循环引用问题. API Reference对__weak变量 ...