加载中…
个人资料
老徐
老徐
  • 博客等级:
  • 博客积分:0
  • 博客访问:827,988
  • 关注人气:156
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

将C/C++代码加入到TCL环境中运行

(2012-07-03 15:22:41)
标签:

c/c

tcl

swig

it

分类: C/CPlusPlus
假设你有一些c你想再加入Tcl, Perl, Python, Java and C#.。举例来说有这么一个文件example.c
 

#include <time.h>
double My_variable = 3.0;
int fact(int n) { if (n <= 1) return 1; else return n*fact(n-1); }
int my_mod(int x, int y) { return (x%y); }
char *get_time() { time_t ltime; time(&ltime); return ctime(&ltime); }

接口文件

现在,为了增加这些文件到你喜欢的语言中,你需要写一个接口文件(interface file)投入到swig中。这些C functions的接口文件可能如下所示:
 
 
%module example
%{
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
%}
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();

【说明】上面蓝色部分的四个函数,如果去掉一个,比如
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
//extern char *get_time();  //注释掉这个函数
则照样可以编译出动态库.so文件,而且该动态库仍然可以被TCL的load命令加载,只是在调用
get_time时会报错:invalid command name "get_time"
但是如果在蓝色部分都加一个不存在的函数,如
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
extern int Noexist_func(int m);//此函数是不存在的
则也可以编译出动态库.so文件,只是在被TCL的load命令加载时
报错couldn't load file "example.so": /home/qfxu/test/swig/example.so: undefined symbol: wrong_func
couldn't load file "***.so": example.so: cannot open shared object file: No such file or directory
这是由于路径不对造成的
解决方法:export LD_LIBRARY_PATH=/home/qfxu/test/swig:$LD_LIBRARY_PATH:

建立Tcl模块

在UNIX系统提示,键入以下信息(LINUX系统请见SWIG WIKI共享库页面其他操作系统帮助):
 unix % swig -tcl example.i

unix % gcc -fpic -c example.c example_wrap.c \ -I/usr/local/include
unix % gcc -shared example.o example_wrap.o -o example.so
unix % tclsh
% load ./example.so
% puts $My_variable 3.0
% fact 5 120
% my_mod 7 3 1
% get_time
 Sun Feb 11 23:01:07 1996
%
该SWIG命令创建了一个文件example_wrap.c,编辑并且和其余的程序联接。在这情况下,我们必须创建一个动态可装载的链接。能够装载进入TCL使用LOAD命令。

SWIG 懒人方法

如上所见,并非总是需要写一个专门的接口文件。如果你有一个头文件,你可以直接在其中包含SWIG接口,如例:
 %module example

%{

 #include "header.h"
%}

%include "header.h"
另外,有些人可能只包括SWIG条件指令在头文件中。例如:
 #ifdef SWIG

%module example
%{
#include "header.h"
%}
#endif
extern int fact(int n); ...

建立Python模块

转换编码C成Python模块很简单,只需要按如下做即可(请见其他操作系统的SWIG共享库帮助手册):
 
 unix % swig -python example.i
 unix % gcc -c example.c example_wrap.c \
        -I/usr/local/include/python2.1
 unix % ld -shared example.o example_wrap.o -o _example.so 
 
我们现在可以使用如下Python模块 :
 >>> import example
 >>> example.fact(5)
 120
 >>> example.my_mod(7,3)
 1
 >>> example.get_time()
 'Sun Feb 11 23:01:07 1996'
 >>>
 

建立Perl模块

你可以建立如下的Perl模块,如Solaris(请见其他操作系统的SWIG共享库帮助手册):
 unix % swig -perl5 example.i
 unix % gcc -c example.c example_wrap.c \
        `perl -MExtUtils::Embed -e ccopts`
 unix % ld -G example.o example_wrap.o -o example.so
 unix % perl
 use example;
 print $example::My_variable,"\n";
 print example::fact(5),"\n";
 print example::get_time(),"\n";
 <ctrl-d>
 3.0
 120
 Sun Feb 11 23:01:07 1996
 unix % 
 

建立Java模块

SWIG也会产生JNI代码以便Jave代码进入C/CC++。以下是建立一个Jave模块的事例(cygwin ,见其他操作系统的swig维基共享库页帮助):
 $ swig -java example.i
 $ gcc -c example.c example_wrap.c -I/c/jdk1.3.1/include -I/c/jdk1.3.1/include/win32
 $ gcc -shared example.o  example_wrap.o -mno-cygwin -Wl,--add-stdcall-alias  -o example.dll
 $ cat main.java
 public class main {
   public static void main(String argv[]) {
     System.loadLibrary("example");
     System.out.println(example.getMy_variable());
     System.out.println(example.fact(5));
     System.out.println(example.get_time());
   }
 }
 $ javac main.java
 $ java main
 3.0
 120
 Mon Mar  4 18:20:31  2002
 $
 

建立C#模块

SWIG也会产生代码以便C#使用Pinvoke进入C/CC++。以下是如何建立C#模块事例。cygwin ,见其他操作系统的swig维基共享库页帮助。使用了开源DotGNU Portable.NET能够在大多数Unix系统上运行,和其他C# compilers一样方便使用:
 $ swig -csharp  example.i
 $ gcc -c -fpic  example.c example_wrap.c
 $ gcc -shared example.o  example_wrap.o   -o libexample.so
 $ cscc -o runme *.cs
 $ cat runme.cs
 using System;
 public class runme {
     static void Main() {
         Console.WriteLine(example.My_variable);
         Console.WriteLine(example.fact(5));
         Console.WriteLine(example.get_time());
     }
 }
 $ ilrun runme
 3
 120
 Tue May 13 10:45:45 2003
 
 $
 

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有