2012-03-16 59 views
2

我需要在一個涉及Progress 9.1D應用程序和C語言函數之間交互的項目中工作。我負責編寫C函數,並且Progress人員要求我調查是否可以發送Progress表並將它作爲結構體在C函數中接收。進度4gl和C結構

我在互聯網上搜索了幾天和一些進度手冊(Progress_External_Programming_Interfaces),但是我已經找到了很少的關於這方面的信息。據我所知,表格可能會作爲MEMPTR變量發送到C函數,但我不確定...

請問,有人可以指點我一些教程或這方面的一個例子嗎?

非常感謝。

回答

1

根據您的平臺,可以調用外部庫,並且有文檔說明如何做(HLC調用我認爲是這樣)。

雖然它無法將整個表發送到庫,這將是可能的:

FOR EACH table-name NO-LOCK: 
    /* transfer table data to memptr */ 
    /* make C call */ 
    /* interpret results */ 
END. 

如果你在一個足夠新版本10 *的是工作,它可能是可能採取一個TT,將其轉換爲MEMPTR中的XML結構,然後將其發送給C代碼。

對於V11.0文檔,它在「OE發展:編程接口」

1

9.1D是在「主機級別的調用接口」當然,古代的,過時的和不支持的,但即便如此它的文檔,支持將C例程調用爲DLL。對於一些詳細的例子,你可能會發現UNIX Shared Libraries這個演示文稿很有幫助。 (底層細節有所不同,但同樣的想法適用於Windows的工作,如果這是你的環境。)的4GL側的

簡單的例子:

define variable x as integer no-undo. 
define variable c as memptr no-undo. 
define variable m as memptr no-undo. 

procedure sprintf external "/lib64/libc.so.6": 
    define input-output parameter fStr as memptr. 
    define input parameter mask as memptr. 
    define input parameter arg as double. 
    define return parameter x as long. 
end. 

set-size(c) = 1024. 
set-size(m) = 1024. 
put-string(m, 1) = "%1.4e". 
run sprintf(input-output c, m, 0.0123, output x). 

display get-string(c, 1) format 「x(20)」. 

return. 

爲您的主要問題,爲C程序員,是提供API和數據結構,4GL人員將能夠輕鬆處理。

最簡單的方法是做簡單的舊的簡單參數(如上圖)。可能每次都有一條記錄(取決於你的功能在做什麼,或者可能沒有意義 - 如果你需要一組記錄來處理,那麼你需要收集它們並以某種方式管理它們)。

如果確實需要創建結構並使用存儲器構建它們,則必須與4GL人緊密合作來定義API並同意memptr應該是什麼樣子。我認爲這可能是很多工作 - 我會盡量避免它,並找到一種方法,如果我可以用簡單的參數。

0

這可以很容易實現:無論是作爲蒂姆·庫恩或湯姆巴斯科姆建議還是:

分配足夠大的存儲區域來保存數據:

def var mp as memptr no-undo. 
set-size(mp) = 1024. /* pre-calculated size depending on the data, in bytes */ 
/* copy contents of temp-table into mp */ 
run procedureInC (mp). /* run external procedure */ 
set-size(mp) = 0. /* free up the memory */ 

有需要三個主要的事情填寫:

  1. 決定如何在內存區域內構建數據,這包括就如何表示4GL數據類型(即表示形式和字符串長度,小數點,日期等)以及良好的理解how your particular C compiler lays out structs in memory
  2. 一旦在第一點上達成一致,4GL可以推出一個函數,給定一個臨時表句柄,根據使用點1和記錄數計算的記錄大小,計算所需的存儲區大小。
  3. 接下來的4GL傢伙可以推出一個程序,將臨時表複製到內存區域,遵循第1點中約定的規則(查看進度手冊中的PUT-BYTE,PUT-STRING等)。

還有一件事要記住,因爲內存區域將由Progress運行時分配,然後在調用C函數後直接釋放內存區域,所以您需要複製內容,一旦你回來,你不會再有空。

  1. 蒂姆的解決方案是從視圖4GL點容易實現的,但是你需要在C解析XML,它會使用顯著更多的內存比其他兩種解決方案。
  2. 湯姆的解決方案是一個妥協。數據以二進制形式發送,但在4GL端需要更多的努力和技巧。你需要推出一個API,管理狀態,數據將在多次連續調用中傳輸。
  3. 我所描述的解決方案就是你所要求的。它允許一次性以最小的開銷傳遞數據。但是,這將取決於配置 - C編譯器生成的結構佈局很重要。

的另一個問題是,第三個解決方案需要在4GL側有人誰理解數據是如何在機器級別代表,所以你可以有關於各種字符串的表示和編碼,字節序,填充進度小數表示一個有意義的對話在C中沒有精度損失,日期表示等等。很明顯,因爲4GL人員要求您調查解決方案,他們可能並不熟悉所有這些主題,因此您最好儘可能簡化任務併爲他們完成大部分工作。

另一種方法是僱用一位適合4GL方面的顧問來爲你做這件事。

還有一種方法是在自己做大量調查和編程工作的同時,在Stackoverflow上詢問更小的問題 - 我們很樂意提供幫助。祝你好運。

0

如果你傳遞的數據不是很大,9.1D有一個相當不錯的基本DOM對象,我將在Progress端使用它構造XML中的數據。然後我將它傳遞給C函數。不知道你的操作系統是什麼,但在Windows中,你可以很容易地將它傳遞給一個COM對象或使用4GL內的EXTERNAL的DLL(由於9.1D的限制,11.0允許你通過.NET的W/O GUI做到這一點)。我們使用Linux和共享庫完成了同樣的事情。 XML方法消除了更改對象的要求。如果您使用的是AppServer,您還可以查看ProxyGen工具。

Don。