我正在尝试为Ø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_VIOLATION
(full 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上编译/运行此代码的许可证吗? : - )
答案 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处理的,我认为这是一种处理问题的安全方法。