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 |
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
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.
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
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 |
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=======--
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
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=======--
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
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
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
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)?
13. Re: Euphoria DLLs
Ah, it looks as if Topica has fixed the problems ...
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 |
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
15. Re: Euphoria DLLs
Juergen Luethje wrote:
> Ah, it looks as if Topica has fixed the problems ...
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
16. Re: Euphoria DLLs
Hello Rob, you wrote:
> Juergen Luethje wrote:
>> Ah, it looks as if Topica has fixed the problems ...
>
> 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.
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 |
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.
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 |
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 ...
>
>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=======--
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 |
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 |
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=======--
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
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
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.
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.