IDL Testing Plan Section 5

從程式與程式間聯接的角度


5. 從程式與程式間聯接的角度

如果一軟體可以很容易地與其他程式做聯接,那這套軟體的擴充能力就
很好,對於解決問題就較有彈性。例如透過pipe的聯接,可以使得許多
既有的工具程式互相與IDL相聯接,這樣除了這些工具程式可以重新再
使用外,在發展時也較容易除錯。

測試IDL程式與其他程式間聯接的問題,因該可分成三個部份:

可以以下面的圖形來表示IDL程式與其他程式間聯接的情形:

5.1. Operating System Access

因為IDL有各種不同平台的版本,所以對於使用作業系統中的功能會有
點差異。基本上在IDL中是使用SPAWN指令來執行作業系統中的其他
程式,當然執行過的結果可以存到IDL中的變數中。

在測試SPAWN指令時,原希望可以執行類似 A | B 的pipe模式,可是
SPAWN指令無法直接執行,必需以變通的方式來達成,例如先寫一
shell script,其中含有所欲執行的指令, A | B ,再以SPAWN指令來執
行此script。

5.2. Child Processes Communication

IDL中的SPAWN,是產生子processes,而在UNIX中,processes之間是
可以相互做通訊的,所以希望測試其Processes Communication的能力。

IDL在SPAWN出一子process後可以有兩種情形,一種是等子process完
成後IDL才繼續執行,另一種是IDL直接繼續執行但是會建立一雙向的
pipe與子process的標準輸入輸出相連接。5.1.節的情形就是前者,而這
兩種情形中後者才是較有彈性的。以下是一個簡單的例子:

fact.c:

#include 

extern int errno;                /* system error number */
extern char *sys_errlist[];      /* system error messages */
extern int sys_nerr;             /* length of sys_errlist */
long fact();
main()
{
  long n=0;
  float i=0;

  setbuf(stdout, (char *) 0);   /* make sure the output is not buffered */

  /*  First argument, find out the N of N!*/
  if (!fread(&n, sizeof(long), 1, stdin)) goto error;
  /*  calculate the N!  */
  i=(float) fact(n);  /*  because the default variable type is float in IDL  */
  if (!fwrite(&i, sizeof(float), 1, stdout)) goto error;
  return;

error:
  fprintf(stderr, " test_pipe: %s\n", sys_errlist[errno]);
}

long fact(n)
long n;
{
  if (n<=0) {return(1);}
  return(n*fact(n-1));
}

test_pipe:

commands='fact'
spawn, commands, unit= unit, /noshell
writeu, unit, 5L
readu, unit, answer
print, '5! = ',answer
free_lun, unit

In IDL:

IDL> @test_pipe
5! =       120.000
IDL> 
相較之下,在Matlab中要與子processes做通訊的話,必需修改子成式的
內容,加入Matlab特有的程式庫,才可以做到。這樣對於舊有程式的重
新再使用就顯得不方便。

5.3. Remoted Procedure Calls

不同於上述兩點中的由IDL程式呼叫其他程式來使用的情形,另外一種
通訊的方式是由一程式中呼叫IDL程式來使用,也就是以IDL程式當
server,使用者自己的程式當client。只要在IDL有提供RPC的各種平台
下,當然client程式與server程式可以位於不同的平台上,不是只能在同
一host之中。

IDL在UNIX版本中提供一個C程式庫,可以讓使用者使用RPCs與IDL做
通訊。這個C程式庫主要包含以下幾類程式:

有了這三類基本的通訊程式庫,是很容易使用RPCs的。但是有一點不方
便是目前IDL只提供C程式庫,若要使用其他的語言來寫client程式,是
不大方便。

以下是一個簡單的例子helloworld.c,他會傳送列印'hello world'的指令
到IDL上:

#include        
#include        
#include        
#include        "export.h"
#include        "rpc_idl.h"

main(c,v)
     int        c;
     char **v;
{
    CLIENT              * client;

    /*  Open connection to server                                       */
    client      = register_idl_client( 0, NULL, NULL );

    /*  See if server exists                                            */
    if( client == NULL )
        printf("Can't find server.\n"), exit(1);

    /*  Send command to server                                          */
    if(send_idl_command( client, "print, 'hello world'" ) != 1 )
        printf("Error encountered sending command!\n");

    /*  Disconnect from server                                          */
    unregister_idl_client( client );
}

[Section 4]|[Table Of Contents]|[Section 6]