2012-03-16 81 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。