Fork me on GitHub

【tcl/tk]】tcl调用tuxedo的一个demo

Tuxedo是Oracle的一个商业中间件,一般用于通信。

如下是一个简单的调用tuxedo的so动态库实现,编译后,tcl脚本可以加载并调用这个so库实现对tuxedo的调用。

1. 代码例子,保存文件为tuxedotcl.cc

#include <stdio.h>
#include <tcl.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <atmi.h>
#include <userlog.h>
#include <time.h>
#include <sys/time.h>
#include <stdarg.h>

extern "C" {
    int Tuxedotcl_Init(Tcl_Interp *Interp);
}

void write_log(const char *fmt, ...) {
    va_list ap;
    int fd;
    char msg[4096];

    va_start(ap, fmt);
    vsnprintf(msg, sizeof(msg), fmt, ap);
    va_end(ap);

    fd = open("tux_tcl.log", O_RDWR|O_APPEND|O_CREAT, 0666);
    if ( fd > 0 ) {
        write(fd, msg, strlen(msg));
        close(fd);
    }    
}

int Action_tpCall(int notUsed, Tcl_Interp *interp, int argc, char **argv)
{
    char retBuffer[512];
    long int sendlen,rcvlen;
    int retCall;
    char *sendbuf;
    char *rcvbuf;

    gettimeofday(&beginTime, NULL);
    memset(retBuffer, 0, sizeof(retBuffer));
    if (argc != 4 && argc != 3) {
        Tcl_SetResult(interp, "Usage::Action_tpCall SERVERNAME sendBuffer WSNADDR", TCL_VOLATILE);
        return TCL_ERROR;
    }
    write_log("Action_tpCall:Begin");
    if ( argv[3][0] != '\0' ) {
        tuxputenv(argv[3]);
    }

    //与服务端创建连接
    if ((tpinit((TPINIT *)NULL)) == -1) {
        write_log("Action_tpCall::Error:Tpinit failed.");
        Tcl_SetResult(interp, "连接初始化失败", TCL_VOLATILE);
        return TCL_ERROR;
    }
    sendlen = strlen(argv[2]);

    //分配发送缓冲区
    if((sendbuf = (char *) tpalloc("STRING", NULL, sendlen+1)) == NULL) {
        write_log("Action_tpCall::Error:allocating send buffer.");
        tpterm();
        Tcl_SetResult(interp, "发送缓存失败", TCL_VOLATILE);
        return TCL_ERROR;
    }

    //分配接收缓冲区
    if((rcvbuf = (char *) tpalloc("STRING", NULL, sendlen+1)) == NULL) {
        write_log("Action_tpCall::Error:allocating receive buffer.");
        tpfree(sendbuf);
        tpterm();
        Tcl_SetResult(interp, "接收缓存失败", TCL_VOLATILE);
        return TCL_ERROR;
    }

    strcpy(sendbuf, argv[2]);

    //调用服务端发送请求方法,并接收返回信息,serverName为服务名
    retCall = tpcall(argv[1],
        (char *)sendbuf, sendlen,
        (char **)&rcvbuf, &rcvlen, TPNOBLOCK);
    if( retCall == -1 ) {
        tpfree(sendbuf);
        tpfree(rcvbuf);
        sprintf(retBuffer, "TUXEDO服务:[%s]", argv[1]);
        Tcl_SetResult(interp, retBuffer, TCL_VOLATILE);
        return TCL_ERROR;
    }
    tpfree(sendbuf);
    tpterm();
    Tcl_SetResult(interp, rcvbuf, TCL_VOLATILE);
    tpfree(rcvbuf);
    return TCL_OK;
}

int Tuxedotcl_Init(Tcl_Interp *Interp) {
    Tcl_CreateCommand (Interp, "Action_tpCall", (Tcl_CmdProc *)Action_tpCall, 0, 0);
    return TCL_OK;
}

  

2. 编译

如果tuxedo安装在本地机器上时,可以简单的进行如下编译。

g++ -fPIC -shared -o libtuxedotcl.so tuxedotcl.cc -I$TUXDIR/include -ltcl -L${TUXDIR}/lib -ltux -lbuft -lfml -lfml32 -lengine -ldl -lpthread

如果tuxedo安装在远端机器上时,编译时需要链接网络相关的库文件 -lwsc -lgpnet

g++ -fPIC -shared -o libtuxedotcl.so tuxedotcl.cc -I$TUXDIR/include -ltcl -L${TUXDIR}/lib -lwsc -lbuft -lgpnet -lfml -lfml32 -lengine -ldl -lpthread

 

3. 执行
$ tclsh
% load libtuxedotcl.so
% Action_tpCall TOUPPER wangyfTestdddd
{0} WANGYFTESTDDDD
% Action_tpCall TOUPPER {This is a toupper test action}
{0} THIS IS A TOUPPER TEST ACTION
%

 

posted @ 2015-12-16 13:10  Mr.YF  阅读(509)  评论(0编辑  收藏  举报