1. Euphoria DLLs

Hi Rob, hi all,

I'm considering buying the Eu2C translator.
The main reason is at the moment, that I'd like to write a plugin for
the Total Commander (formerly known as Windows Commander,
http://www.ghisler.com/). The plugin is technically just a DLL.

In the description of the plugin API, there is for instance:
int __stdcall ProcessFile (HANDLE hArcData, int Operation, char*DestPath,
   char *DestName)

That looks to me, as if my DLL must be able to exchange addresses, i.e.
*32*-bit integer values with the Total Commander (floating point values
are not requiered at all). But in "e2c.htm" (Eu 2.4 Beta), it reads:
"Euphoria .dlls (.so's) can be used by C programs as long as only 31-bit
integer values are exchanged."
So is it not possible to write a plugin for the Total Commander (and
probably for many other commercial programs) with Euphoria?

I already created a test version of that DLL with the Public Domain
Translator (using the Borland C++ Compiler 5.5 on Windows 98), and
interestingly it works! Does this just happen by chance, because the
Total Commander maybe up to now only sended 31-bit values to my DLL, or
can this DLL be considered reliable?
How big are the chances that a future version of the translator will
create DLLs (and SOs) that exchange 32-bit integer values with C
programs?

The Total Commander is well known, and translated to many languages.
Because I also will release the DLL source code, then there probably
would be a link from http://www.ghisler.com/plugins.htm to Euphoria's
'Recent User Contributions' Page. So I think writing such a plugin would
not only be useful for users of Total Commander, but also make Euphoria
better known all over the world.

Best regards, and Happy Easter,
   Juergen

-- 
 /"\  ASCII ribbon campain  |
 \ /  against HTML in       |  Money is the root of all evil.
  X   e-mail and news,      |  Send 20 Dollars for more info.
 / \  and unneeded MIME     |

new topic     » topic index » view message » categorize

2. Re: Euphoria DLLs

Hello Rob,

thanks for your reply. You wrote:

> Juergen Luethje wrote:

[...]

> Things are guaranteed to work if 31-bit integers are
> passed. If a 32-bit integer is passed in from C,
> things might still work (all the time),
> depending on what you do with that value.

The 32 bit values that are passed in from the main
program [1] to my DLL are memory addresses, that the
DLL code uses for peek()ing and poke()ing.

> You would have to examine the
> C code generated by the Translator in each case
> to determine if 32-bits will work.

What rules shall I use to make such decisions?
Unfortunately, I almost don't know anything about C
programming.

> If necessary, you could code your own little C
> routine, and make that the entry point to
> your .dll. It could then handle any 32-bit arguments,
> before calling one of your Translator-generated routines.
> In general, it could simply convert each C 32-bit integer
> into a Euphoria atom (C double) with one C statement.

Maybe you (or someone else) could give me a template or
an example how to do this?

>> How big are the chances that a future version
>> of the translator will create DLLs (and SOs)
>> that exchange 32-bit integer values with C programs?
>
> It depends on how many people need this.
> So far I haven't seen many people wanting to call
> Euphoria .dll's from C.

If Euphoria could produce industry standard DLLs, I
think it also could be for instance very useful for
Visual Basic programmers to use a DLL created with
Euphoria to speed up critical parts of their code.

TIA, and best regards,
   Juergen

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

3. Re: Euphoria DLLs

Again code is nipped on this list ...
Second trial:

Hello Rob,

thanks for your reply. You wrote:

> Juergen Luethje wrote:

[...]

> Things are guaranteed to work if 31-bit integers are
> passed. If a 32-bit integer is passed in from C,
> things might still work (all the time),
> depending on what you do with that value.

The 32 bit values that are passed in from the main
program [1] to my DLL are memory addresses, that the
DLL code uses for peek()ing and poke()ing.

> You would have to examine the
> C code generated by the Translator in each case
> to determine if 32-bits will work.

What rules shall I use to make such decisions?
Unfortunately, I almost don't know anything about C
programming.

> If necessary, you could code your own little C
> routine, and make that the entry point to
> your .dll. It could then handle any 32-bit arguments,
> before calling one of your Translator-generated routines.
> In general, it could simply convert each C 32-bit integer
> into a Euphoria atom (C double) with one C statement.

Maybe you (or someone else) could give me a template or
an example how to do this?

>> How big are the chances that a future version
>> of the translator will create DLLs (and SOs)
>> that exchange 32-bit integer values with C programs?
>
> It depends on how many people need this.
> So far I haven't seen many people wanting to call
> Euphoria .dll's from C.

If Euphoria could produce industry standard DLLs, I
think it also could be for instance very useful for
Visual Basic programmers to use a DLL created with
Euphoria to speed up critical parts of their code.

TIA, and best regards,
   Juergen

--=----=---=---=---=---=---=---=---=--
[1] The main program that calls my DLL (Total Commander)
    is actually written in Delphi, not in C. I don't know
    whether that matters here.

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

4. Re: Euphoria DLLs

Juergen Luethje wrote:
>>Things are guaranteed to work if 31-bit integers are
>>passed. If a 32-bit integer is passed in from C,
>>things might still work (all the time),
>>depending on what you do with that value.
> 
> 
> The 32 bit values that are passed in from the main
> program [1] to my DLL are memory addresses, that the
> DLL code uses for peek()ing and poke()ing.
> 
> 
>>You would have to examine the
>>C code generated by the Translator in each case
>>to determine if 32-bits will work.
> 
> 
> What rules shall I use to make such decisions?
> Unfortunately, I almost don't know anything about C
> programming.

If you don't know C, it will be difficult to know
if everything is OK.

>>If necessary, you could code your own little C
>>routine, and make that the entry point to
>>your .dll. It could then handle any 32-bit arguments,
>>before calling one of your Translator-generated routines.
>>In general, it could simply convert each C 32-bit integer
>>into a Euphoria atom (C double) with one C statement.
> 
> 
> Maybe you (or someone else) could give me a template or
> an example how to do this?

I'll make a little example, and add it
to the documentation.

>>>How big are the chances that a future version
>>>of the translator will create DLLs (and SOs)
>>>that exchange 32-bit integer values with C programs?
>>
>>It depends on how many people need this.
>>So far I haven't seen many people wanting to call
>>Euphoria .dll's from C.
>
> If Euphoria could produce industry standard DLLs, I
> think it also could be for instance very useful for
> Visual Basic programmers to use a DLL created with
> Euphoria to speed up critical parts of their code.
> 
> TIA, and best regards,
>    Juergen
> 
> --=----=---=---=---=---=---=---=---=--
> [1] The main program that calls my DLL (Total Commander)
>     is actually written in Delphi, not in C. I don't know
>     whether that matters here.

The data types are probably very similar to C.

By the way, this annoying Topica problem is also
happening on other Topica lists. Topica is aware of it.
I hope they fix it soon. I'm going to remove the
"Euphoria Mailing List" title line in the Topica
admin page. Maybe that will help.

Regards,
    Rob Craig
    Rapid Deployment Software
    http://www.RapidEuphoria.com

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

5. Re: Euphoria DLLs

These are just
some "dummy lines",
that perhaps will
be deleted by Topica.


Hello Rob,

you wrote:

> If you don't know C, it will be difficult to know
> if everything is OK.
>
>>> If necessary, you could code your own little C
>>> routine, and make that the entry point to
>>> your .dll. It could then handle any 32-bit arguments,
>>> before calling one of your Translator-generated routines.
>>> In general, it could simply convert each C 32-bit integer
>>> into a Euphoria atom (C double) with one C statement.
>>
>>
>> Maybe you (or someone else) could give me a template or
>> an example how to do this?
>
> I'll make a little example, and add it
> to the documentation.

[...]

Thank you very much!

Best regards,
   Juergen

-- 
 /"\  ASCII ribbon campain  |
 \ /  against HTML in       |  Money is the root of all evil.
  X   e-mail and news,      |  Send 20 Dollars for more info.
 / \  and unneeded MIME     |

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

6. Re: Euphoria DLLs

--=======4AA91555=======

At 01:49 AM 4/21/03 -0400, Rob Craig wrote:
> >>Things are guaranteed to work if 31-bit integers are
> >>passed. If a 32-bit integer is passed in from C,
> >>things might still work (all the time),
> >>depending on what you do with that value.
> >
> >
> > The 32 bit values that are passed in from the main
> > program [1] to my DLL are memory addresses, that the
> > DLL code uses for peek()ing and poke()ing.
> >

<snip>

>>>It depends on how many people need this.
>>>So far I haven't seen many people wanting to call
>>>Euphoria .dll's from C.
<snip>

         I started on a potentially commercial project that requires this 
and got stalled by the same thing.  A calling program( language unknown ) 
is required to pass a pointer to a buffer that it provides to receive an 
error message.  Sometimes it works; sometimes it doesn't and says "A 
machine exception occurred ...".  I was wondering if this could be an issue 
with the page being swapped out at the time but this is not an interrupt 
service routine.  By the way, the program I tested my DLL with is written 
in Euphoria.

         Rob, could you come up with an example of this that works?

                 Thanks,

                 Bob

--=======4AA91555=======
Content-Type: text/plain; charset=us-ascii; x-avg=cert;
x-avg-checked=avg-ok-64D7360B
Content-Disposition: inline


---

--=======4AA91555=======--

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

7. Re: Euphoria DLLs

Robert Elia wrote:
> I started on a potentially commercial project that requires this 
> and got stalled by the same thing.  A calling program( language unknown 
> ) is required to pass a pointer to a buffer that it provides to receive 
> an error message.  Sometimes it works; sometimes it doesn't and says "A 
> machine exception occurred ...".  I was wondering if this could be an 
> issue with the page being swapped out at the time but this is not an 
> interrupt service routine. By the way, the program I tested my DLL with 
> is written in Euphoria.

You can safely pass *any* Euphoria data (atoms and sequences)
from a Euphoria program to a Euphoria .dll and back.

I assume you wanted to call the Euphoria .dll from
a C (or similar) program, and were just testing
it from a Euphoria program, using define_c_proc() and
C_INT, C_POINTER etc. parameter declarations, instead of 
E_INTEGER, E_ATOM etc.

I assume you can edit the main program,
in which case you can break the buffer pointer
into *two* 16-bit arguments, pass them separately,
and then recombine them into a single 32-bit pointer
(*atom* variable, not integer) in the Euphoria subroutine.
In C you would do something like:

      int hi16, lo16;

      lo16 = (unsigned)p & 0x0000FFFF;
      hi16 = ((unsigned)p  >> 16) & 0x0000FFFF;
      eu_routine(hi16, lo16);

Then in Euphoria, you'd have:
      procedure eu_routine(integer hi16, integer lo16)
      atom p
      p = hi16 * #10000 + lo16

      ? peek(p) -- etc.

This approach should always work (unless I've made a
coding error!), and avoids the uncertainties of passing
32-bit data from a non-Euphoria program to a Euphoria .dll.

Regards,
    Rob Craig
    Rapid Deployment Software
    http://www.RapidEuphoria.com

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

8. Re: Euphoria DLLs

--=======79C1671C=======

At 09:45 PM 4/22/03 -0400, you wrote:
> > I started on a potentially commercial project that requires this
> > and got stalled by the same thing.  A calling program( language unknown
> > ) is required to pass a pointer to a buffer that it provides to receive
> > an error message.  Sometimes it works; sometimes it doesn't and says "A
> > machine exception occurred ...".  I was wondering if this could be an
> > issue with the page being swapped out at the time but this is not an
> > interrupt service routine. By the way, the program I tested my DLL with
> > is written in Euphoria.
>
>
>You can safely pass *any* Euphoria data (atoms and sequences)
>from a Euphoria program to a Euphoria .dll and back.
>
>I assume you wanted to call the Euphoria .dll from
>a C (or similar) program, and were just testing
>it from a Euphoria program, using define_c_proc() and
>C_INT, C_POINTER etc. parameter declarations, instead of E_INTEGER, E_ATOM 
>etc.

Yes.

>I assume you can edit the main program,
>in which case you can break the buffer pointer
>into *two* 16-bit arguments, pass them separately,
>and then recombine them into a single 32-bit pointer
>(*atom* variable, not integer) in the Euphoria subroutine.
>In C you would do something like:
<snip>

No, I cannot edit the main program because I won't be writing it.  It would 
be developed separately by any number of persons with whom I have no 
contact.  The API of my DLL is specified in a published document.  E.G.:

C / C++ Prototype
extern "C" long WINAPI GetLastError
(
char *pErrorDescription
)

The calling program is required to allocate a buffer and pass a pointer to 
the function in the DLL.  The DLL must then poke a string into the buffer.

         I tried to make a simple example but that ALWAYS fails. ( a clue 
perhaps ? )

         Does anyone know if the buffer allocated by the caller is 
automatically made available (i.e. is given write permission) to the 
DLL?  Could there be some WIN32 API function to lock the memory that I ( or 
perhaps Euphoria's allocate() ) need to call?

         Since I don't have the EU source, I can only guess at what might 
be happening.  As my function often DOES work, I suspect there might be 
some flag that allocate() should use internally in this situation.

         It's just very frustrating to not be able to use my favorite 
language for this.

         Thanks for the reply,

                 Bob     

--=======79C1671C=======
Content-Type: text/plain; charset=us-ascii; x-avg=cert;
x-avg-checked=avg-ok-713B265C
Content-Disposition: inline


---

--=======79C1671C=======--

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

9. Re: Euphoria DLLs

Robert Elia wrote:
 > No, I cannot edit the main program because I won't
 > be writing it.  It would be developed separately
 > by any number of persons with whom I have
 > no contact.  The API of my DLL is specified
 > in a published document.  E.G.:
 >
 > C / C++ Prototype
 > extern "C" long WINAPI GetLastError
 > (
 > char *pErrorDescription
 > )
 >
 > The calling program is required to allocate a buffer
 > and pass a pointer to the function in the DLL.
 > The DLL must then poke a string into the buffer.

Here's a trick that might work.
Declare the Euphoria routine something like this:

       procedure GetLastError(int pErrorDescription)
            atom p

            p = 0.0 + pErrorDescription

            poke(p, "Error: Just testing" & 0)
       end procedure

Regards,
    Rob Craig
    Rapid Deployment Software
    http://www.RapidEuphoria.com

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

10. Re: Euphoria DLLs

Robert Craig wrote:
>      procedure GetLastError(int pErrorDescription)

Whoops. That should be:
        procedure GetLastError(integer pErrorDescription)

In my example, it's important that you declare the parameter as
integer and not atom.

If you need to return an int value to C
(up to 31-bits), make it a function instead of a procedure.

Regards,
    Rob Craig
    Rapid Deployment Software
    http://www.RapidEuphoria.com

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

11. Re: Euphoria DLLs

-jeez Rob, are you a Euphoria programmer or a c programmer?? ;]


>From: Robert Craig <rds at RapidEuphoria.com>
>Subject: Re: Euphoria DLLs
>
>
>Robert Craig wrote:
>>      procedure GetLastError(int pErrorDescription)
>
>Whoops. That should be:
>        procedure GetLastError(integer pErrorDescription)
>
>In my example, it's important that you declare the parameter as
>integer and not atom.
>
>If you need to return an int value to C
>(up to 31-bits), make it a function instead of a procedure.
>
>Regards,
>    Rob Craig
>    Rapid Deployment Software
>    http://www.RapidEuphoria.com
>
>
>
>TOPICA - Start your own email discussion group. FREE!
>
>


_________________________________________________________________
Help STOP SPAM with the new MSN 8 and get 2 months FREE*  
http://join.msn.com/?page=features/junkmail

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

12. Re: Euphoria DLLs

Rob, why did you use:

>            p = 0.0 + pErrorDescription

instead of just:

             p = pErrorDescription

Is this some quirk to save cycles that you haven't told us about (or that 
i've just missed)?

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

13. Re: Euphoria DLLs

Ah, it looks as if Topica has fixed the problems ... smile

Robert Elia had written previously:

| The calling program is required to allocate a buffer and pass a pointer
| to the function in the DLL.  The DLL must then poke a string into the
| buffer.

Robert Craig replied:

>         procedure GetLastError(integer pErrorDescription)
>
> In my example, it's important that you declare the parameter as
> integer and not atom.

Then Robert Elia must write in the documentation of the API of his DLL,
that the pointer can only have a value in the 31-bit range, right?

Best regards,
   Juergen

-- 
 /"\  ASCII ribbon campain  |
 \ /  against HTML in       |  Money is the root of all evil.
  X   e-mail and news,      |  Send 20 Dollars for more info.
 / \  and unneeded MIME     |

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

14. Re: Euphoria DLLs

stabmaster_ at hotmail.com wrote:
> Rob, why did you use:
> 
>            p = 0.0 + pErrorDescription
> 
> instead of just:
> 
>             p = pErrorDescription
> 
> Is this some quirk to save cycles that you haven't 
 > told us about (or that i've just missed)?

A simple assignment would just copy (as is)
the improper 32-bit integer value
(passed in by the C program) into p
By performing a computation, it creates
a proper Euphoria atom, i.e. it creates an 8-byte
floating-point number to store the 32-bit integer value.

This trick can work because the translator does
not optimize-away additions by 0.0, nor does it
type-check parameter values.
(Note: I still haven't fully-tested this stuff.
I'm hoping the two interested people will try it.)

Regards,
    Rob Craig
    Rapid Deployment Software
    http://www.RapidEuphoria.com

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

15. Re: Euphoria DLLs

Juergen Luethje wrote:
> Ah, it looks as if Topica has fixed the problems ... smile

I think Topica is still screwed up, but ListFilter
is inserting an extra empty blank line at the start of each
EUforum message body. That seems to fix the problem.
In an e-mail message, an empty line marks the end of
the header and the start of the body.
 From what I've read on the List Owners list,
Topica is (often) missing this boundary and is
including the first part of a message in the header.

> Robert Elia had written previously:
> 
> | The calling program is required to allocate a buffer and pass a pointer
> | to the function in the DLL.  The DLL must then poke a string into the
> | buffer.
> 
> Robert Craig replied:
> 
>>        procedure GetLastError(integer pErrorDescription)
>>
>>In my example, it's important that you declare the parameter as
>>integer and not atom.
> 
> 
> Then Robert Elia must write in the documentation of the API of his DLL,
> that the pointer can only have a value in the 31-bit range, right?

No, that's the point of the trick.
I believe by doing this little (untested) trick of adding 0.0,
he will be able to handle 32-bit pointers and other values,
reliably. The documentation for his .dll needn't
say anything about 31 vs 32 bits.

Regards,
    Rob Craig
    Rapid Deployment Software
    http://www.RapidEuphoria.com

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

16. Re: Euphoria DLLs

Hello Rob, you wrote:

> Juergen Luethje wrote:
>> Ah, it looks as if Topica has fixed the problems ... smile
>
> I think Topica is still screwed up, but ListFilter
> is inserting an extra empty blank line at the start of each
> EUforum message body. That seems to fix the problem.

Thank you, I appreciate it.

[...]

>> Robert Elia had written previously:
>>
>>| The calling program is required to allocate a buffer and pass a pointer
>>| to the function in the DLL.  The DLL must then poke a string into the
>>| buffer.
>>
>> Robert Craig replied:
>>
>>>        procedure GetLastError(integer pErrorDescription)
>>>
>>> In my example, it's important that you declare the parameter as
>>> integer and not atom.
>>
>>
>> Then Robert Elia must write in the documentation of the API of his DLL,
>> that the pointer can only have a value in the 31-bit range, right?
>
> No, that's the point of the trick.
> I believe by doing this little (untested) trick of adding 0.0,
> he will be able to handle 32-bit pointers and other values,
> reliably. The documentation for his .dll needn't
> say anything about 31 vs 32 bits.

Grmpf... I had forgotten, that the translator doesn't type-check
parameter values. But now the penny has dropped. smile

Thanks, and best regards,
   Juergen

-- 
 /"\  ASCII ribbon campain  |  while not asleep do
 \ /  against HTML in       |     sheep += 1
  X   e-mail and news,      |  end while
 / \  and unneeded MIME     |

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

17. Re: Euphoria DLLs

Hello Rob, you wrote:

[...]
>>            p = 0.0 + pErrorDescription
[...]

> By performing a computation, it creates
> a proper Euphoria atom, i.e. it creates an 8-byte
> floating-point number to store the 32-bit integer value.
>
> This trick can work because the translator does
> not optimize-away additions by 0.0, nor does it
> type-check parameter values.
> (Note: I still haven't fully-tested this stuff.
> I'm hoping the two interested people will try it.)

If it works, that would be cool. smile
I'll do some testing this weekend with the Public Domain translator.
My registration for the translator is on it's way (by snail mail),
so I'll be able to release my DLL soon, and hopefully other users of the
Total Commander then also will test it.

Best regards,
   Juergen

-- 
 /"\  ASCII ribbon campain  |  while not asleep do
 \ /  against HTML in       |     sheep += 1
  X   e-mail and news,      |  end while
 / \  and unneeded MIME     |

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

18. Re: Euphoria DLLs

--=======ED17E4A=======

At 12:34 PM 4/25/03 -0400, you wrote:

>>Ah, it looks as if Topica has fixed the problems ... smile
>
>I think Topica is still screwed up, but ListFilter
>is inserting an extra empty blank line at the start of each
>EUforum message body. That seems to fix the problem.
>In an e-mail message, an empty line marks the end of
>the header and the start of the body.
> From what I've read on the List Owners list,
>Topica is (often) missing this boundary and is
>including the first part of a message in the header.
>
>>Robert Elia had written previously:
>>| The calling program is required to allocate a buffer and pass a pointer
>>| to the function in the DLL.  The DLL must then poke a string into the
>>| buffer.
>>Robert Craig replied:
>>
>>>        procedure GetLastError(integer pErrorDescription)
>>>
>>>In my example, it's important that you declare the parameter as
>>>integer and not atom.
>>
>>Then Robert Elia must write in the documentation of the API of his DLL,
>>that the pointer can only have a value in the 31-bit range, right?
>
>No, that's the point of the trick.
>I believe by doing this little (untested) trick of adding 0.0,
>he will be able to handle 32-bit pointers and other values,
>reliably. The documentation for his .dll needn't
>say anything about 31 vs 32 bits.
>
>Regards,
>    Rob Craig

Sorry to keep you waiting, I've been doing a lot of testing.

         Actually, I wouldn't be expected to write any documentation.  A 
person writing a program to use my DLL would use the same public 
documentation that describes the API as I use to write the DLL.  That's the 
problem.

         I tried your "trick", Rob, but got the same unpredictable 
behavior.  I even tried allocating the buffer with:

         pErrorDescription = c_func(GlobalAlloc, {GMEM_FIXED, 500})
         pErrorDescription = c_func(GlobalLock, {pErrorDescription})

from KERNEL32.DLL.  ...made no difference.  ctrace_d.out shows the poke in 
the DLL function as the last statement executed.

Two days later....

         I've managed to get a stripped down version working okay.  It 
didn't need Rob's trick. The problem must be somewhere else.  If I find it, 
I'll post it.  After that, the next step is to write a test program in C.

                 Thanks again,

                 Bob

--=======ED17E4A=======
Content-Type: text/plain; charset=us-ascii; x-avg=cert;
x-avg-checked=avg-ok-5EF1982
Content-Disposition: inline


---

--=======ED17E4A=======--

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

19. Re: Euphoria DLLs

I wrote:

[...]
> I'll do some testing this weekend with the Public Domain translator.
[...]

I made a DLL and a wrapper for it (Eu 2.4 Beta on Windows 98):

------------------------------------------------------------------>8---
file 'the.ew'
-----==---------------------------------------------------------==-----
-- I compiled this file to a DLL, using the Borland C++ Compiler 5.5

global procedure test_1 (integer fn, integer pntr)
   printf(fn, "procedure test_1: %d\n", {pntr})
end procedure

global procedure test_2 (integer fn, integer pntr)
   atom p
   p = 0.0 + pntr
   printf(fn, "procedure test_2: %d\n", {pntr})
end procedure

type dword (object x)
   -- This is for testing another idea.
   -- Using a user defined type for a parameter, that must be converted
   -- to an atom, would improve the readability of the code.
   return integer(x)
end type

global procedure test_3 (integer fn, dword pntr)
   atom p
   p = 0.0 + pntr
   printf(fn, "procedure test_3: %d\n", {pntr})
end procedure
------------------------------------------------------------------>8---


------------------------------------------------------------------>8---
file 'call_dll.exw'
-----==---------------------------------------------------------==-----
include dll.e

constant STDOUT = 1
atom dll, addr
integer test_1, test_2, test_3

dll = open_dll("the.dll")
test_1 = define_c_proc(dll, "test_1", {C_INT, C_UINT})
test_2 = define_c_proc(dll, "test_2", {C_INT, C_UINT})
test_3 = define_c_proc(dll, "test_3", {C_INT, C_UINT})

-- All 3 procedures will run OK:
addr = power(2,31) - 1
c_proc(test_1, {STDOUT, addr})
c_proc(test_2, {STDOUT, addr})
c_proc(test_3, {STDOUT, addr})

-- All 3 procedures will crash with the error message
-- "A machine-level exception occurred during execution of this statement":
addr = power(2,31)
c_proc(test_1, {STDOUT, addr})
c_proc(test_2, {STDOUT, addr})
c_proc(test_3, {STDOUT, addr})
------------------------------------------------------------------>8---


Using  addr = power(2,31) - 1  was OK,
using  addr = power(2,31)      caused a crash in all three cases.

If I didn't make a mistake somewhere in this test, it looks as if even
the trick in procedure test_2() doesn't work.

Best regards,
   Juergen

-- 
 /"\  ASCII ribbon campain  |
 \ /  against HTML in       |  Money is the root of all evil.
  X   e-mail and news,      |  Send 20 Dollars for more info.
 / \  and unneeded MIME     |

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

20. Re: Euphoria DLLs

Hello Bob, you wrote:

[...]

>          I tried your "trick", Rob, but got the same unpredictable
> behavior.  I even tried allocating the buffer with:
>
>          pErrorDescription = c_func(GlobalAlloc, {GMEM_FIXED, 500})
>          pErrorDescription = c_func(GlobalLock, {pErrorDescription})
>
> from KERNEL32.DLL.  ...made no difference.  ctrace_d.out shows the poke in
> the DLL function as the last statement executed.

In the other message that I posted at almost the same time than this one,
there is a test in which I didn't allocate any memory at all.
If I didn't make a mistake somewhere in that test, it looks as if it
simply isn't possible, to pass a value bigger than  power(2,31) - 1
as argument to a routine in the DLL (without using E_ATOM etc.,
of course).

> Two days later....
>
>          I've managed to get a stripped down version working okay.  It
> didn't need Rob's trick.

Maybe you didn't pass any value bigger than power(2,31) - 1
as argument to a routine in the DLL?

> The problem must be somewhere else.  If I find it,
> I'll post it.  After that, the next step is to write a test program in C.
>
>                  Thanks again,
>
>                  Bob

I hope, we will solve this puzzle.

Best regards,
   Juergen

-- 
 /"\  ASCII ribbon campain  |
 \ /  against HTML in       |  Money is the root of all evil.
  X   e-mail and news,      |  Send 20 Dollars for more info.
 / \  and unneeded MIME     |

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

21. Re: Euphoria DLLs

--=======180448EA=======

At 07:17 PM 4/27/03 +0200, you wrote:

>
>Hello Bob, you wrote:
>
>[...]
>
> >          I tried your "trick", Rob, but got the same unpredictable
> > behavior.  I even tried allocating the buffer with:
> >
> >          pErrorDescription = c_func(GlobalAlloc, {GMEM_FIXED, 500})
> >          pErrorDescription = c_func(GlobalLock, {pErrorDescription})
> >
> > from KERNEL32.DLL.  ...made no difference.  ctrace_d.out shows the poke in
> > the DLL function as the last statement executed.
>
>In the other message that I posted at almost the same time than this one,
>there is a test in which I didn't allocate any memory at all.
>If I didn't make a mistake somewhere in that test, it looks as if it
>simply isn't possible, to pass a value bigger than  power(2,31) - 1
>as argument to a routine in the DLL (without using E_ATOM etc.,
>of course).
>
> > Two days later....
> >
> >          I've managed to get a stripped down version working okay.  It
> > didn't need Rob's trick.
>
>Maybe you didn't pass any value bigger than power(2,31) - 1
>as argument to a routine in the DLL?

Yes, that's true.  All pointers that were passed were in the 5,000,000 
range.  Obviously, we can't depend on that happening in all environments.

> > The problem must be somewhere else.  If I find it,
> > I'll post it.  After that, the next step is to write a test program in C.
> >
> >                  Thanks again,
> >
> >                  Bob
>
>I hope, we will solve this puzzle.

Me too.  I imagine that it would be required to do things like make plugins 
in EU.

                 Bob

--=======180448EA=======
Content-Type: text/plain; charset=us-ascii; x-avg=cert;
x-avg-checked=avg-ok-7B5246B7
Content-Disposition: inline


---

--=======180448EA=======--

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

22. Re: Euphoria DLLs

I think that 0.0 + eu_integer doesn't convert eu_integer to to an
unsign 32 bit value.
If you try this:

atom m
m =3D allocate ( 4 )

function ulong ( integer  i )

    poke4 ( m , i )
    return  peek4u ( m )=20

end function


-George

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

23. Re: Euphoria DLLs

Here is a walkthrough of what I did:

1) Create the Euphoria file that we want to make into a DLL....

--test.ew
global function tChangeVolProc(atom lp1, atom lp2, integer v)
atom lpname
-- 'Fix' the pointer...
lpname = lp1 * #10000 + lp2
printf(1, "%d\n", {lpname})
   return lpname --this doesn't return right, though....
                 -- probably for the same reason as you
                 -- can't pass higher than 31-bit integers
end function

global function tProcessDataProc(atom lp1, atom lp2, integer v)
atom lpname
integer len
-- 'Fix' the pointer
lpname = lp1 * #10000 + lp2
printf(1, "%d\n", {lpname})
len = 0
-- Can we access it?
while peek(lpname + len) do len += 1 end while
printf(1, "%s\n", {peek({lpname, len})})
    return 34 --any number below some limit,
              -- not sure what the limit is though....
end function
--end

The functions are global so that we may find them. Also, they take two 
parameters wherever it requires a pointer. These functions don't do anything 
in particular....

2) Translate the file to C...
We will end up with seven files: test.c, test.def, init_.c, emake.bat, 
main_.c, main_.h and objfiles.lnk.

3) Now, we have to fix the C source...
  3a) Look in test.def to see what your functions have been renamed as. It 
should contain something like the following:

EXPORTS
tChangeVolProc=_0tChangeVolProc
tProcessDataProc=_0tProcessDataProc

  We can see that the translator has added _0 to the names of our functions. 
We will need this later...

  3b) At the end of the C source file, test.c, we will add:

//Begin
int __stdcall tChangeVolProc(char *ArcName, int Mode) {
    return _0tChangeVolProc((int)((((int)ArcName)>>16)&0xffff),
           (int)(((int)ArcName)&0xffff), Mode);
}

int __stdcall tProcessDataProc(char *FileName, int Size) {
    return _0tProcessDataProc( (int)((((int)FileName)>>16)&0xffff),
           (int)(((int)FileName)&0xffff), Size);
}
//End

In these two functions, we used the two names of the Euphoria functions that 
we found in test.def. The functions take one parameter as a pointer and 
translates it to two parameters (High word, then Low word). (I probably have 
too many parentheses, but better safe than sorry.)

  3c) The last edit is to fix test.def...
  Now that we have actual C functions, we should remove the part that 
references the Euphoria functions. Remove the ='s and the names following 
it. Test.def should now look like this:

EXPORTS
tChangeVolProc
tProcessDataProc

The C function names will now be exported, instead of the Euphoria 
functions.

  4) Run emake.bat
This will give you a DLL.

To test this DLL, use the following Euphoria code:

--Begin test_ptr.exw
include dll.e
include machine.e

constant
the_dll = open_dll("test.dll"),
tChangeVolProc = define_c_func(the_dll, "tChangeVolProc", {C_POINTER, 
C_INT}, C_INT),
tProcessDataProc = define_c_func(the_dll, "tProcessDataProc", {C_POINTER, 
C_INT}, C_INT),
lpstring = allocate_string("assdfse")

printf(1, "%d, %d", {
                      --Use a constant value, will always be
			c_func(tChangeVolProc, {#FFF43FFF, 4}),
			c_func(tProcessDataProc, {lpstring, 2})})
free(lpstring)
while get_key() = -1 do end while
--End

If you would like to try some C code:

// Begin test_ptr.c
#include <stdio.h>

extern int __stdcall tChangeVolProc(char *, int);
extern int __stdcall tProcessDataProc(char *, int);

int main (int argc, char **argv) {
	printf("%d, %d",
			tChangeVolProc((char *)0xfff43fff, 4),
			tProcessDataProc("assdfse", 2));
	return 0;
}
//End

To compile this:
1) Run: implib test.lib test.dll
2) Run: bcc32 -WC test_ptr.c test.lib
3) Run: test_ptr

  This is compiled with the Borland C++ 5.5.1 Command-line Compiler. It 
appears to work properly.

  HTH,
Elliott Sales de Andrade

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

24. Re: Euphoria DLLs

Hello Elliott, you wrote:

>   Here is a walkthrough of what I did:

[...]

>   This is compiled with the Borland C++ 5.5.1 Command-line Compiler.
> It appears to work properly.
>
>  HTH,
> Elliott Sales de Andrade

Thank you _very_ much for the comprehensive and foolproof advice!!
I use the same compiler, and everything works fine. Now I can build
plugins with Euphoria. Great!!

Best regards,
   Juergen

-- 
Q: How many Microsoft engineers does Bill need to change a light bulb?
A: None. He just declares darkness to be an industry standard.

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

25. Re: Euphoria DLLs

Hello George, you wrote:

> I think that 0.0 + eu_integer doesn't convert eu_integer to to an
> unsign 32 bit value.
> If you try this:
>
> atom m
> m = allocate ( 4 )
>
> function ulong ( integer  i )
>
>     poke4 ( m , i )
>     return  peek4u ( m )
>
> end function
>
>
> -George

When using this inside a DLL, and calling the function similar to the
way I did in my test posted on 2003-04-27, unfortunately the error
message "A machine-level exception occurred during execution of this
statement" is raised, too.

Thanks for the suggestion, and best regards,
   Juergen

-- 
Q: How many Microsoft engineers does Bill need to change a light bulb?
A: None. He just declares darkness to be an industry standard.

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

Search



Quick Links

User menu

Not signed in.

Misc Menu