ØMQC函数(共享库/ .dll)绑定导致zmq_init硬崩溃

时间:2012-04-27 04:49:09

标签: progress-4gl

我正在尝试为ØMQ C library编写ABL绑定,但是正在崩溃我的zmq_init函数绑定的过程编辑器。我写了binding for zmq_version没有问题,所以我认为它不是.dll文件问题。无论如何,C函数原型看起来像这样:

void *zmq_init (int io_threads);

我写的ABL代码如下:

PROCEDURE zmq_init EXTERNAL "libzmq.dll" CDECL:
  DEFINE INPUT  PARAMETER num_threads AS LONG.
  DEFINE RETURN PARAMETER context_ptr AS MEMPTR.
END PROCEDURE.

DEF VAR mContext AS MEMPTR NO-UNDO.
RUN zmq_init(INPUT 0, OUTPUT mContext).

此特定函数初始化“0mq上下文”(潜在问题:它是一个线程池)并返回指向它的指针。错误是否与OpenEdge的非线程特性有关,即使我正在调用外部库并请求在池中分配0个线程?

在“过程编辑器”中运行代码会导致Windows“进度客户端已停止工作”时出现错误Exception code: C0000005 ACCESS_VIOLATIONfull stack trace此处出现错误,尽管我并不总是会获得包含信息的堆栈跟踪它)。

我从未完成过Windows C编程,但如果我在Unix上使用gcc(访问受保护的内存),它看起来就像我称之为分段错误。说到这一点,我实际上宁愿在Unix机器上运行这个代码,但显然Progress只为Windows提供评估开发人员OE环境:(。

我已禁用DEP但没有成功。当ABL从库中返回时,ABL是否试图取消引用指针?当然必须有一种方法来处理签名,返回值为void *,在库调用中得到malloc。

我浏览了OpenEdge Development: Programming Interfaces,Tom Bascom的UNIX Shared Libraries PowerPoint以及其他一些名为OpenEdge in an LDAP World的PowerPoint,其中包含一些代码示例,但没有看到任何明显的我遗漏的内容

我使用的是OpenEdge 10.2B,Windows 7 64位,但使用的是32位版本的OpenEdge,因为这是我评估软件的唯一选择。任何人都可以借用在CentOS上编译/运行此代码的许可证吗? : - )

3 个答案:

答案 0 :(得分:2)

在宣布您的程序时,您缺少 PERSISTENT 关键字。

请尝试以下代码:

zmq.p

&SCOPED DLLNAME 'libzmq.so'
PROCEDURE zmq_init EXTERNAL {&DLLNAME} CDECL PERSISTENT:
    DEF INPUT  PARAMETER NumThreads AS LONG.
    DEF RETURN PARAMETER Context AS MEMPTR.
END PROCEDURE.

PROCEDURE zmq_term EXTERNAL {&DLLNAME} CDECL PERSISTENT:
    DEF INPUT  PARAMETER Context  AS MEMPTR.
    DEF RETURN PARAMETER ResultStatus AS LONG.
END PROCEDURE.

PROCEDURE zmq_version EXTERNAL {&DLLNAME} CDECL PERSISTENT:
    DEF OUTPUT PARAMETER major AS LONG.
    DEF OUTPUT PARAMETER minor AS LONG.
    DEF OUTPUT PARAMETER patch AS LONG.
END PROCEDURE.

<强> check_zmq.p

DEF VAR Zmq AS HANDLE NO-UNDO.
DEF VAR MajorVersion AS INT NO-UNDO.
DEF VAR MinorVersion AS INT NO-UNDO.
DEF VAR PatchVersion AS INT NO-UNDO.

DEF VAR CallStatus AS INT NO-UNDO.

DEF VAR ZmqContext AS MEMPTR NO-UNDO.

RUN zmq.p PERSISTENT SET Zmq.

RUN zmq_version IN Zmq ( OUTPUT MajorVersion, OUTPUT MinorVersion, OUTPUT PatchVersion ).
MESSAGE MajorVersion MinorVersion PatchVersion.

RUN zmq_init IN Zmq ( 1, OUTPUT ZmqContext ).
RUN zmq_term IN Zmq ( ZmqContext, OUTPUT CallStatus ).
MESSAGE CallStatus.

FINALLY:
    IF VALID-HANDLE(Zmq) THEN
         DELETE PROCEDURE Zmq.
END FINALLY.

答案 1 :(得分:1)

  

错误是否与OpenEdge的非线程特性有关,即使我正在调用&gt;外部库并请求在池中分配0个线程?

我遇到了几次相同的问题(Progress Client已停止工作),而我正在研究一些c#方法(通过clr bridge调用),其中我使用了线程。 通过使用一些c#库类(AsyncOperation,AsyncCallback)来隐藏线程,解决了这个问题,但大多数尝试都导致进度运行时停止。

与.net相关的进度帮助声明“你不能使用System.Threading.Thread,或任何派生类 - ABL是单线程的。”

我知道通过clr bridge调用c#方法与调用c库完全不同,但也许我们的问题是由OpenEdge的单线程特性引起的。

答案 2 :(得分:1)

我从github抓取你的代码并将MEMPTR变量更改为INT64。这使它能够在不崩溃的情况下运行(在64位Windows 7上为10.2b05 32位)。由于内存是由zeromq处理的,我认为这是一种处理问题的安全方法。