Prayer

在一般中寻求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

BCB 客户端 tuxedo 开发实例

Posted on 2008-12-11 15:07 Prayer 阅读(1293) 评论(0)  编辑 收藏 引用 所属分类: TUXEDO
 

BCB 客户端 tuxedo 开发实例
-supermgr

在BCB中怎样使用tuxedo呢?

本文给出了一个例子。

然而,这个例子在后来被证明还是有点问题的,

就是在tpcall调用后,无法释放dll,而且会出错。

这一问题咨询过tuxedo,多少年过去了,我还没有

得到问题的解。

 

tuxedo 的函数很多,所有应用都使用其中子集。这些函数子集包含在开发

包中一定的动态库中。下面以

tpinit,tpcall,tpterm,tpfree,tpalloc,Fget32,Fchg32,FLDOCC32 几个函数为

例介绍一下在该子集下的编程方式。(不是很准哟)

1、首先 找到这些函数所在的动态库。经过解析发现以上函数包含        

    在wtuxws32.dll,libfml32.dll 两个动态库中。多好,有了这两个动

   态库,应用程序发行时,带上他们就可以了。再也不会出现 操作系统弹出

   的动态库定位错误了。 且慢,后经研究发现,光有这两个dll不行,他们

   的运行还需如下6个dll:libbuft.dll,libengine.dll,libfml.dll,
 
   libgpnet.dll,libtux.dll,libwsc.dll。 哈哈。总算解析完了。

   好,把这些文件copy出来到自己的工程目录下。多棒。赶紧进入下一步。

2、配置编译环境。这很重要。为使大家编程方便,我们做些小动作。在

   BCB 的安装目录下(即$(BCB)标识的目录)建立tuxedo\目录,将

   tuxedo开发包中的 \bin\,\include\,\lib\几个目录拷贝到该目录下。
  
   然后,在Option|Directories/Conditionals中设置
  
    Include Path :   $(BCB)\Tuxedo\include
    Library Path :   $(BCB)\Tuxedo\lib
   
    好了,环境设置好了。在你的工程中include :
    #include <atmi.h>
    #include <fml32.h>
    #include <tmenv.h>
   
    哦,他们三个文件实在太重要了,不包含进来你会后悔的:)
   
3、建立一个tuxedo子集函数结构。为什么这样做呢,直接使用tuxedo函数

   不好吗? 这没什么的,依个人编程环境而定。我习惯于在结构名下
  
   使用这些 外来开发包中的函数,因为你对他们不是很熟,有时会遗忘
  
   其名称,将其放在结构中,利用BCB自动提示功能,你就可以很容易
  
   找到(想起)需要的函数了。我定义的结构如下:
  
 typedef
 struct _FunTuxedo
 {
 
  int
  (_TMDLLENTRY *
  tpcall)(char _TM_FAR *,
   char _TM_FAR *,
   long ,
   char _TM_FAR * _TM_FAR *,
   long _TM_FAR *,
   long );
   
  int
  (_TMDLLENTRY *
  tpinit)(TPINIT _TM_FAR *);
  
  int
  (_TMDLLENTRY *
  tpterm)(void);
  void
  (_TMDLLENTRY *
  tpfree)(char _TM_FAR *);
  
  char *
  (_TMDLLENTRY *
  tpalloc)(char _TM_FAR *,
      char _TM_FAR *,
      long);
  
  int
  (_TMDLLENTRY *
  Fget32)(FBFR32 _TM_FAR *,
     FLDID32,
     FLDOCC32,
     char _TM_FAR *,
     FLDLEN32 _TM_FAR *);
  
  
  int
  (_TMDLLENTRY *
  Fchg32)(FBFR32 _TM_FAR *,
     FLDID32,
     FLDOCC32,
     char _TM_FAR *,
     FLDLEN32);
  FLDOCC32
  (_TMDLLENTRY *
  Foccur32)( FBFR32 _TM_FAR *,
    FLDID32);
  
  HMODULE hLibfml32; // libfml32.dll 动态库句柄
  HMODULE hWtuxws32; // wtuxws32.dll 动态库句柄
 
 }FUNTUXEDO,*PFUNTUXEDO;
 
    这里,我将两个动态库句柄加入到了结构中,是因为我打算动态使用
   
   tuxedo中间件。方便我释放他们。,下一节介绍装载/释放他们
  
4 装载、释放中间件(基于FUNTUXEDO结构)

   哈,这很容易,主要用到LoadLibrary,FreeLibrary,GetProcAddress
  
   三个函数。装载代码如下:
  
    PFUNTUXEDO pFun;      
 
    //Loading Fchg32, Fget32 by LIBFML32.DLL
    pFun->hLibfml32 = LoadLibrary(libfml32.dll);
    if (pFun->hLibfml32 == NULL)
    {
     return -1;
    }
   
    (FARPROC &)pFun->Fchg32
     =(FARPROC)GetProcAddress(pFun->hLibfml32,Fchg32);
    (FARPROC &)pFun->Fget32
     =(FARPROC)GetProcAddress(pFun->hLibfml32,Fget32);
 (FARPROC &)pFun->Foccur32
     =(FARPROC)GetProcAddress(pFun->hLibfml32,Foccur32);       
           
    if (pFun->Fchg32 == NULL || pFun->Fget32 == NULL || pFun->Foccur32 == NULL)
    {
     FreeLibrary(pFun->hLibfml32);
        pFun->hLibfml32 = NULL;
     return -2;
    }
 //Loading tpacall, tpalloc, tpfree, tpinit, tpterm by WTUXWS32.DLL
 pFun->hWtuxws32 = LoadLibrary(wtuxws32.dll);
    if (pFun->hWtuxws32 == NULL)
    {
     FreeLibrary(pFun->hLibfml32);
        pFun->hLibfml32 = NULL;       
     return -3;
    }   
       
    (FARPROC &)pFun->tpcall
     =(FARPROC)GetProcAddress(pFun->hWtuxws32,tpacall);                                 
    (FARPROC &)pFun->tpalloc
     =(FARPROC)GetProcAddress(pFun->hWtuxws32,tpalloc);
    (FARPROC &)pFun->tpfree
     =(FARPROC)GetProcAddress(pFun->hWtuxws32,tpfree);
    (FARPROC &)pFun->tpinit
     =(FARPROC)GetProcAddress(pFun->hWtuxws32,tpinit);
    (FARPROC &)pFun->tpterm
     =(FARPROC)GetProcAddress(pFun->hWtuxws32,tpterm);        
                       
    if (pFun->tpcall == NULL || pFun->tpalloc == NULL ||
     pFun->tpfree == NULL || pFun->tpinit  == NULL ||
        pFun->tpterm == NULL)
    {
     FreeLibrary(pFun->hLibfml32);
        pFun->hLibfml32 = NULL;       
        FreeLibrary(pFun->hWtuxws32);
 pFun->hWtuxws32 = NULL;
        return -4;
    }    
  
   释放时很简单,只需
        FreeLibrary(pFun->hLibfml32);         
        FreeLibrary(pFun->hWtuxws32);
   即可。

(注:传统情况下,FreeLibrary(DllHandle) 是不会出问题的。但在

BEA 公司 的 这些dll面前,ms 的 FreeLibrary 就不行了,当应用程序

退出时,会有非法地址访问的问题。我检查过数次,只要一经调用tpcall

,退出时就会有问题。)

  折衷的办法是 使用 try-catch,释放时不使用FreeLibrary,

而在应用程序退出时,最后使用 FreeLibraryAndExitThread,否则即使

你使用FreeLibrary 也没法通过 catch 捕捉到异常。呵呵。


   
 5、使用。例:...的内容查帮助吧。
 
    PFUNTUXEDO pFun;   
    char *pSendBuff;
    char *pRecvBuff;
    long lRet;
    short sRet;
    int iRet;    
   
   
    //中间件服务
   
    pSendBuff = pFun->tpalloc(...);
    if (pSendBuff == NULL)
    {
     return ERR_TUXEDO;
    }
   
    pRecvBuff = pFun->tpalloc(...);
    if (pRecvBuff == NULL)
    {
     pFun->tpfree(pSendBuff);
        return ERR_TUXEDO;
    }
   
    try
    {   
    iRet = pFun->Fchg32(...);
    if (iRet == -1)
    {
     throw(1);
    }                   
   
    //建立连接
    iRet = pFun->tpinit(NULL);
    if (iRet == -1)
    {
     throw(2);
    }                       
     
    iRet = pFun->tpcall(...);
    if (iRet == -1)
    {
     throw(3);
    }     
   
    iRet = pFun->tpterm();
    if (iRet == -1)
    {
     throw(4);       
    }
    iRet =pFun->Fget32(...);
    if (iRet == -1)
    {
     throw(4);       
    }                         
   
    pFun->tpfree(pSendBuff);
    pFun->tpfree(pRecvBuff);
   
    }
    catch(int Err)
    {                   
     pFun->tpfree(pSendBuff);
  pFun->tpfree(pRecvBuff);
        return Err;
    }
    catch(...)
    {
     return ERR_UNKNOWN;
    }   

    //这里可以处理接收到的数据结果
    //...  
     
6、编译。

 

注意,这里有一个问题。当tpcall后,释放dll时,有一点麻烦。

后来发现的。

2003-7


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理