1. RE: cdecl support

I looked at Mic's routines but they left me confused and it looked like 
a bit of a hack job.

For working with cab files, you might want to look into the Setup API:

>From SDK:
You can extract files from a cabinet in two ways. The first and simplest 
way is to take advantage of the automatic cabinet processing built into 
the setup functions.

<snipped details>

The second way to extract files from a cabinet is by using 
SetupIterateCabinet.  This function iterates through each file in a 
cabinet, sending a notification to a callback routine for each file 
found. The callback routine then returns a value that indicates whether 
the file should be extracted or skipped.

I haven't used them myself but I don't think they require cdecl calls 
(being Windows CALLBACKs and all...)

-- Brian

Euman wrote:
> Hi Brian
> 
> I gave up about a week ago trying to get it to work properly.
> I  tried Matts routines, Mic has some routines in his GLU project
> and some of my own routines that never seemed to work right.
> 
> I can get handles to the Euphoria routine but when a .dll requires
> that these routines (Eu routines) be cdecl also, I threw up my hands.
> 
> I too would like a work around cause I wanted to use cabinet.dll
> to extract files from compressed MS-Cab's.
> 
> Euman
> euman at bellsouth.net
> 
> Q: Are we monetarily insane?
> A: YES
> ----- Original Message ----- 
> From: "Brian Broker" <bkb at cnw.com>
> To: "EUforum" <EUforum at topica.com>
> Sent: Monday, February 25, 2002 3:16 PM
> Subject: cdecl support
> 
> 
> > For Matt Lewis and/or Euman:  Did you guys come up with a relatively 
> > clean solution for defining cdecl callbacks?
> > 
> > For Robert Craig:  How long before a 2.4 alpha with cdecl support?
> > 
> > For anybody with source:  Anybody willing to build me a PD interpreter 
> > with cdecl support?  I'm getting frustrated without it.
> > 
> > Thanks,
> > -- Brian
> > 
> >

new topic     » topic index » view message » categorize

2. RE: cdecl support

Derek Parnell wrote:
> I suppose some enterprising person could write a "conversion" DLL. One 
> that accepts Euphoria 
> parameters, passes them onto the _cdecl routine and returns the _cdecl 
> results to Euphoria?
> 
> I have no idea if this is possible or how hard it might be; just a 
> thought.
> 

That's what I did with the Karl's regex wrapper, which crashes when 
translated due to this problem.  I made a middleman dll as we talked 
about last time that simply passes through the parameters to the real 
dll, and then passes back the result.  Works fine. I'm going to make 
another for the SQL-Lite library, which has the same problem.  I used 
the BCX basic to c translator with LCC.  Using that, you can make your 
middleman .dll in just a couple of minutes.  I'll post the method if 
anyone is interested.

I don't know of way to make a universal one -- you have to put in 
equivalents for each individual function. You also have to add one extra 
initialization function, so the first .dll will open up the second one.

If you need to set up callbacks back to a Euphoria routine, I have no 
idea how to do that...

new topic     » goto parent     » topic index » view message » categorize

3. RE: cdecl support

Robert Craig wrote:
> Brian Broker writes:
> > For Robert Craig:  How long before a 2.4 alpha with cdecl support?
> 
> I don't know. It depends on how long it takes to accumulate
> enough bug fixes and new features to justify the (considerable)
> overhead of doing a release. It could be 3 months to a year I suppose.
> 
> > For anybody with source:  Anybody willing to build 
> > me a PD interpreter with cdecl support?  I'm getting 
> > frustrated without it.
> 
> A quick hack could be easily done by someone with the source
> to create a second form of c_proc() and c_func() that would
> use a cdecl call. I don't have time to do quick hacks for one person
> or a few people. I'd like to find the best long-term solution.
> 
> 
How would the long-term solution be different from this "quick hack" -- 
isn't that all we need?

new topic     » goto parent     » topic index » view message » categorize

4. RE: cdecl support

-------Phoenix-Boundary-07081998-

Hi Andy Serpa, you wrote on 2/25/02 4:29:54 PM:

>
>That's what I did with the Karl's regex wrapper, which crashes when
>translated due to this problem.
>

What is 'this problem' ?

Karl

-------Phoenix-Boundary-07081998---

new topic     » goto parent     » topic index » view message » categorize

5. RE: cdecl support

kbochert at ix.netcom.com wrote:
> -------Phoenix-Boundary-07081998-
> Content-type: text/plain; charset=ISO-8859-1
> Content-transfer-encoding: 8bit
> 
> Hi Andy Serpa, you wrote on 2/25/02 4:29:54 PM:
> 
> >
> >That's what I did with the Karl's regex wrapper, which crashes when
> >translated due to this problem.
> >
> 
> What is 'this problem' ?
> 
> Karl
> 

The functions in the .dll are supposed to be called using cdecl 
(Remember the thread a month or so back when I brought this up?  Look up 
thread "Program crash with regex wrapper after translation" from 
January.) -- it works only by luck because of the way Watcom compiles 
(apparently) when using the interpreter, but crashes if you translate it 
to C with Borland or LCC.  Specifically, it crashes with any call to 
regex_free, but I noticed later that you get corruption in general with 
any call.

Your wrapper isn't the only one, as I noted -- the SQL lite library and 
probably a bunch of others will not work when translated, and only 
"happen" to work with the interpreter -- in other words, you are on 
shaky ground period with any .dll that expects cdecl calls, which 
outside of the WinAPI, is a lot of them.  Practically anything that has 
been ported from UNIX, or is not Windows-specific will have this problem 
I imagine.  In any case, this instability was enough for me to keep away 
from these libraries, even with the interpreter.  But with my middleman 
.dll, all is well, if inelegant.

Andy Serpa
renegade at earthling.net

new topic     » goto parent     » topic index » view message » categorize

6. RE: cdecl support

Robert Craig wrote:
> Andy Serpa writes:
> > How would the long-term solution be different from 
> > this "quick hack" -- isn't that all we need?
> 
> I'd like to do some research before I implement 
> a solution to _cdecl. For instance, I'd be happier
> if Euphoria could detect the need for cdecl, rather
> than having the programmer worry about it.
> 
> Adding "quick hack" solutions to a programming
> language is easy. Removing those quick hacks once
> people start to use them is extremely difficult.
> I don't want Euphoria to accumulate a lot of quick hacks
> that are later made obsolete when a better solution
> is implemented.
> 

The technical term for what we're talking about is the "Foreign Function 
Interface" for the language, a term I learned when I was trying to 
figure out how to get around this. (Just do a search on that phrase to 
learn more.)  I checked on how some other languages handled it, and 
although there are some function naming conventions that often indicate 
the calling convention of a foreign function, you can't count on them 
definitively. In the description of their FFI for all the other 
languages I found, specifying the calling convention is always done by 
the programmer themselves, so I get the impression dectecting it 
reliably is dicey.

Plus, not detecting it actually has one advantage:  adding support for 
any other calling convention besides cdecl could be done under the same 
framework, simply by adding another legal value to the parameter that 
specifies the convention...

new topic     » goto parent     » topic index » view message » categorize

7. RE: cdecl support

> -----Original Message-----
> From: euman at bellsouth.net [mailto:euman at bellsouth.net]

> I gave up about a week ago trying to get it to work properly.
> I  tried Matts routines, Mic has some routines in his GLU project
> and some of my own routines that never seemed to work right.
>
> I can get handles to the Euphoria routine but when a .dll requires
> that these routines (Eu routines) be cdecl also, I threw up my hands.
>
> I too would like a work around cause I wanted to use cabinet.dll
> to extract files from compressed MS-Cab's.
>
> Euman
> euman at bellsouth.net

> > From: "Brian Broker" <bkb at cnw.com>
> > For Matt Lewis and/or Euman:  Did you guys come up with a
> relatively
> > clean solution for defining cdecl callbacks?
> >
> > For Robert Craig:  How long before a 2.4 alpha with cdecl support?
> >
> > For anybody with source:  Anybody willing to build me a PD
> interpreter
> > with cdecl support?  I'm getting frustrated without it.

I finally had some time to look at the problem in detail.  I've got cdecl
callbacks to Euphoria working (ie, you can call Eu routines using cdecl),
and I think I figured out how to call a cdecl routine (had an epiphany right
before bed last night).  Here's how to make a cdecl callback:

-- Start code
include machine.e
include misc.e
include dll.e

constant
func_asm = {

    #55,                    --    0: push ebp
    #89,#E5,                --    1: mov ebp, esp
    #51,                    --    3: push ecx
    #B9,#00,#00,#00,#00,    --    4: mov ecx, argnum (5)
    #89,#E6,                --    9: mov esi, esp
    #83,#C6,#0C,            --    B: add esi, 12
    #BF,#00,#00,#00,#00,    --    E: mov edi, myargs (15)
    #F3,#A5,                --   13: rep movsd; next we call the proc

    #FF,#15,#00,#00,#00,#00,--   15: call dword ptr [pfunc] (#17)

    #59,                    --   1B: pop ecx
    #89,#EC,                --   1C: mov esp, ebp
    #5D,                    --   1E: pop ebp
    #C2,#00,#00,#00,#00}    --   1F: ret [argnum] (#20)


constant offset = length( func_asm )

global function new_pfunc_cdecl( atom callback, integer args )
    atom func_addr, func_retval, func_pfunc, func_args

    func_addr = allocate( length(func_asm) + 4 * 12  )
    poke( func_addr, func_asm )
    func_retval = func_addr + offset
    func_pfunc = func_retval + 4
    func_args = func_pfunc + 4

    poke4( func_addr + #05, args )
    poke4( func_addr + #0F, func_args )
    poke4( func_addr + #17, func_pfunc )
    --poke4( func_addr + #20, ( args + 0 ) * 4 )

    poke4( func_pfunc, callback )

    return { func_addr, func_args }
end function

atom my_cdecl_args
function my_cdecl_func()
    sequence args
    args = peek4u( {my_cdecl_args , 2})
    -- do stuff
    return 1
end func

object my_cdecl_callback

my_cdecl_callback = new_pfunc_cdecl( call_back(routine_id("my_cdecl_func")),
2 )

my_cdecl_args = my_cdecl_callback[2]
my_cdecl_callback = my_cdecl_callback[1]
-- Now you can pass my_cdecl_callback to a dll that uses cdecl

new topic     » goto parent     » topic index » view message » categorize

8. RE: cdecl support

-------Phoenix-Boundary-07081998-

Hi Andy Serpa, you wrote on 2/25/02 6:38:18 PM:

>
>The functions in the .dll are supposed to be called using cdecl
>(Remember the thread a month or so back when I brought this up?  Look up
>thread "Program crash with regex wrapper after translation" from
>January.)
>

Thanks for the reminder - it had completely slipped my mind.

> -- it works only by luck because of the way Watcom compiles
>(apparently) when using the interpreter, but crashes if you translate it
>to C with Borland or LCC.  Specifically, it crashes with any call to
>regex_free, but I noticed later that you get corruption in general with
>any call.
>

The interpreter uses the _stdcall convention.

According to Borland:
_stdcall  -- arguments pushed right-to-left
          -- callee cleans the stack
_cdecl    -- arguments pushed right-to-left
          -- caller cleans the stack

When the Watcom interpreter calls a _cdecl routine (like in
regex.dll) some junk gets left on the stack, but it gets
ignored by Watcom's exit code.

The LCC interpreter attempts to exit by popping saved
registers (which are the junk left by the C call - disaster.).

If the interpreter pops the stack after the C call,
it is using the _cdecl convention and either Watcom or
LCC work fine on regex.dll. (verified)

The interpreter could be easily modified to save the stack
address at the start of its 'call_c' routine and restore it
directly after the C call, thereby handling either _cdecl
or _stdcall, with any compiler. Basically, two assembly
fragments are needed: save_stk() and restore_stk().

Is it really that simple, or am I overlooking something?

I would guess that this approach could also
be applied to the translator.

Can someone supply me with a reasonably small
_stdcall DLL to verify my code on?

Karl Bochert

-------Phoenix-Boundary-07081998---

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu