ØMQ C function (shared library / .dll) binding causing hard crash - Forum - OpenEdge General - Progress Community

ØMQ C function (shared library / .dll) binding causing hard crash

 Forum

ØMQ C function (shared library / .dll) binding causing hard crash

  • (Note: I cross-posted this to StackOverflow if you prefer getting points)

    (Update: I see ZeroMQ was already discussed here, but it looks like the only bindings written were for .NET)

    I'm trying to write an ABL binding for the ØMQ C library, but am crashing the Procedure Editor for my zmq_init function binding.  I wrote a binding for zmq_version without issue, so I assume it's not a .dll file problem.  Anyway, the C function prototype looks like this:

    void *zmq_init (int io_threads);

    The ABL code I've written is as follows:

    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).

    This particular function initializes a "0mq context" (potential problem: it's a thread pool) and returns a pointer to it.  Could the error be related to OpenEdge's non-threaded nature, even though I'm calling an external library and requesting 0 threads be allocated in the pool?

    Running the code in Procedure Editor makes it crash with a Windows "Progress Client has stopped working" error with

    Exception code: C0000005 ACCESS_VIOLATION

    (full stack trace here, although I don't always get a stack trace with info in it).

    I've never done Windows C programming, but it looks like what I'd call a Segmentation Fault if I were on Unix using gcc (accessing protected memory).  Speaking of which, I'd in fact rather run this code on a Unix machine but apparently Progress only provides evaluation developer OE environments for Windows .

    I've disabled DEP without success.  Is ABL trying to dereference the pointer when it returns from the library or something?  Surely there has to be a way to handle signatures with a return value of void* that get malloc'ed in the library call.

    I've paged through OpenEdge Development: Programming Interfaces, Tom Bascom's UNIX Shared Libraries PowerPoint, and some other PowerPoint called OpenEdge in an LDAP World that has some code samples but don't see anything obvious that I'm missing.

    I'm on OpenEdge 10.2B, Windows 7 64-bit, however using the 32-bit version of OpenEdge as that's my only option for evaluation software.  Anyone got a license I could borrow for running this code on CentOS?

  • Anyone got a license I could borrow for running this code on CentOS?

    Back in the OpenEdge world?

    Contact you Progress sales rep or regional office and request a trial license for your desired platform.

  • Haha, nope, just visiting for "fun".  I emailed Progress w/ the form on their website, so we shall see.  I'm definitely not going to pay for it.

  • FYI, the .NET bindings for 0MQ work fine with OpenEdge

  • Cool, thanks, I will check that out if I can't get the ABL bindings to work.

  • OK, I don't think it's the binding that is the problem. When I pass a value < 0 in for the number of threads, I don't get a crash and instead get a null pointer, as I would expect looking at the source.  And when I do pass in a value >= 0, it does return a pointer back momentarily before crashing (I can view the address). So I'm guessing it's something to do with the AVM's lack of threading support...?  Perhaps the .NET example works because the 0MQ calls are running within the CLR, which I assume supports threading.

    Anyway, I'll probably just give up on this as I doubt it's viable.  Too bad, too - it could have been a cleaner way of doing IPC than named pipes or ABL's ugly SOCKET.  The solution is probably to just use the existing .NET binding, which is pretty clean besides the ABL type conversions.  Unfortunately it's not a solution for Unix.

    The code is here if anyone ever wants to monkey with it. test_context.p is what to run if you try to fix the zmq_init binding.