BCB 客戶端 tuxedo 開發例項

mrhaozi發表於2010-01-22

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)Tuxedoinclude
Library Path : $(BCB)Tuxedolib

好了,環境設定好了。在你的工程中include :
#include
#include
#include

哦,他們三個檔案實在太重要了,不包含進來你會後悔的:)

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、編譯。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16396910/viewspace-1030809/,如需轉載,請註明出處,否則將追究法律責任。

相關文章