为Tcl编写C的扩展库
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的扩展库的更多相关文章
- 如何编写自己的Arduino库?
一开始写Arduino 的时候很不习惯,没有main函数,因为好多东西都被隐藏了.一直想搞清楚,以便编写自己的库文件.于是研究一下午,下面是一些总结. Arduino工程的初步认识 一.目录规范 当你 ...
- PHP扩展编写、PHP扩展调试、VLD源码分析、基于嵌入式Embed SAPI实现opcode查看
catalogue . 编译PHP源码 . 扩展结构.优缺点 . 使用PHP原生扩展框架wizard ext_skel编写扩展 . 编译安装VLD . Debug调试VLD . VLD源码分析 . 嵌 ...
- php笔记08:数据库编程---使用php的MySQL扩展库操作MySQL数据库
1.使用php的MySQL扩展库操作MySQL数据库: php有3种方式操作MySQL数据库 (1)mysql扩展库 (2)mysqli扩展库 (3)pdo mysql扩展库与mysql数据库 ...
- Python和C++的混合编程(使用Boost编写Python的扩展包)
想要享受更轻松愉悦的编程,脚本语言是首选.想要更敏捷高效,c++则高山仰止.所以我一直试图在各种通用或者专用的脚本语言中将c++的优势融入其中.原来贡献过一篇<c++和js的混合编程>也是 ...
- 『Python CoolBook』C扩展库_其一_用法讲解
不依靠其他工具,直接使用Python的扩展API来编写一些简单的C扩展模块. 本篇参考PythonCookbook第15节和Python核心编程完成,值得注意的是,Python2.X和Python3. ...
- JavaScript学习总结(十四)——JavaScript编写类的扩展方法
在JavaScript中可以使用类的prototype属性来扩展类的属性和方法,在实际开发当中,当JavaScript内置的那些类所提供的动态 ...
- 使用php的mysqli扩展库操作mysql数据库
简单介绍mysqli: 1.mysqli(mysql improve mysql扩展库的增强版) mysql扩展库和mysqli扩展库的区别 1.mysqli的稳定性 安全性 和 执行效率有所提高 ...
- scrapy进阶-编写中间件和扩展
中间件: 主要讨论的是下载中间件,明确一下顺序: download_middlewares --> server.url ---> spider_middleware 我主 ...
- php数据库编程---mysqli扩展库
1,mysqli扩展库允许我们访问MySQL数据库,并对MySql数据库进行curd操作.Mysqli扩展库比mysql扩展库加强了. 2,mysqli扩展库和mysql扩展库的比较 (1) mysq ...
随机推荐
- hibernate报ExceptionInInitializerError错误
今天在练习hibernate的criteria接口查询时候报了错: java.lang.ExceptionInInitializerError at test.testThisPro.createCr ...
- NYOJ 105
九的余数 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 现在给你一个自然数n,它的位数小于等于一百万,现在你要做的就是求出这个数整除九之后的余数. 输入 第一行有一个整 ...
- Winform布局方式
一.默认布局 ★可以加panel,也可以不加: ★通过鼠标拖动控件的方式,根据自己的想法布局.拖动控件的过程中,会有对齐的线,方便操作: ★也可选中要布局的控件,在工具栏中有对齐工具可供选择,也有调整 ...
- Nginx编译参数.md
Nginx 介绍 简介 Nginx(发音同engine x)是一个网页服务器,它能反向代理HTTP, HTTPS, SMTP, POP3, IMAP的协议链接,以及一个负载均衡器和一个HTTP缓存. ...
- Moto C118 基于 Osmocom-BB 和 OpenBTS 搭建小型GSM短信基站
此文章PDF文档下载地址:点击下载 0x00 写在前面 大家应该都听说过摩托罗拉C118配合Osmocom-BB实现GSM网络下的短信拦截功能吧,在14年左右新出了一种玩法就是Osmocom-BB的s ...
- jquery-抖动图组轮播动画
JQ匀速抖动图组轮播动画 一.HTML+CSS <!DOCTYPE html> <html lang="en" xmlns="http://www.w3 ...
- 【Python】[进程和线程]多进程,多线程,ThreadLocal,进程VS.线程,分布式进程
1.多进程,multiprocessing模块, 进程间的通信:Queue[队列],Pipes[管子]2.多线程, 注意:线程公用变量,混乱 解决方法Lock:因为只有一个锁,所以当要执 ...
- VIM编辑器常用命令
一.剪切: 1. 欲从当前光标删除至下一个单词,请输入:dw 2. 欲从当前光标删除至当前行末尾,请输入:d$ 3. 欲删除整行,请输入:dd //可以使用 dNd删除多行 N代表行数 4. 欲 ...
- 使用js实现显示系统当前时间并实现倒计时功能并触发模态框(遮罩)功能
常常在我们的网页中需要倒计时来触发一些函数,例如遮罩等,在本项目中,通过使用jquery,bootstrap,实现了显示系统当前时间,并且实现了倒计时的功能,倒计时实现后将会弹出模态框(遮罩层).模态 ...
- mtr命令详解
原文地址:http://blog.hexu.org/archives/1050.shtml 一般在windows 来判断网络连通性用ping 和tracert,ping的话可以来判断丢包率,trace ...