为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 ...
随机推荐
- Android(Linux)控制GPIO的方法及实时性分析
Linux下控制GPIO的方法有N种,详细请参考<RPi GPIO Code Samples>,文中用十多种语言演示了如何控制GPIO,非常全面详尽.因此,这里不再多做赘述,仅把调试过程中 ...
- IntelliJ IDEA 乱码解决方案 (项目代码、控制台等)
IntelliJ IDEA 乱码解决方案 (项目代码.控制台等) 最近IDE从eclipse改成IntelliJ IDEA 了,原因是公司大部分人都在用这个IDE,而且一直推荐用,所以尝尝鲜.换的第一 ...
- Visual Studio 2013支持Xamarin的解决方案
转自博客园[遗忘的代码] Xamarin的Visual Studio插件目前还不支持VS 2013,所以需要在安装Xamarin的VS插件时把2010和2012全选上 (由于我的电脑里只剩2013,而 ...
- 初识CDQ分治
[BZOJ 1176:单点修改,查询子矩阵和]: 1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 200 ...
- return false
”return false“到底做了什么? 当你每次调用”return false“的时候,它实际上做了3件事情: •event.preventDefault();•event.stopPropaga ...
- 国内外前端(js)开发框架对比
国内外前端开发框架对比 首先我们先对目前国内外主流前端开发框架做一个基本的了解,之后再对他们进行一个直观的对比. Bootstrap Bootstrap(http://www.bootcss.com) ...
- 【C#】【Thread】SpinWait
System.Threading.SpinWait 是一个轻量同步类型,可以在低级别方案中使用它来避免内核事件所需的高开销的上下文切换和内核转换. 在多核计算机上,当预计资源不会保留很长一段时间时,如 ...
- maven更改编译环境的java版本
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> ...
- NPOI导出Excel合并表头写入公式
protected void Btn1_Click(object sender, EventArgs e) { //建立空白工作簿 IWorkbook workbook = new HSSFWorkb ...
- JsonPropertyOrder无法为DTO对象进行属性排序
在项目中,遇到一个问题,无论怎么设置JsonPropertyOrder,都无法正确实现排序功能,问题代码如下: @JsonPropertyOrder(value={"courseId&quo ...