1. Problem calling my C DLL from a IDE created source

I have spent all day trying to figure out why my Euphoria windows program
cannot access my DLL. I have determined that in fact it does access it, but
that the arguments are passed wrong. So, I made a test case for this forum.

Here is my C code compiled with the Watcom C compiler and linked to a
Win32 NT DLL:

#if defined(__cplusplus)
#define EXPORTED extern "C" __declspec( dllexport )
#else
#define EXPORTED __declspec( dllexport )
#endif


EXPORTED int dll_entry( int arg )
{
	return (arg + arg);
}

------------

Here is the code from the IDE:

--  code generated by Win32Lib IDE v0.22.0 Build Dec-16-2006

constant TheProgramType="exw" 
 
include Win32lib.ew
without warning

--------------------------------------------------------------------------------
--  Window Window1
constant Window1 = createEx( Window, "Window1", 0, Default, Default, 400, 300,
0, 0 )
---------------------------------------------------------
--------------------------------------------------------------------------------
-- Test code in Window1 general

include dll.e -- this is for calling the dll written in C

atom dll
integer entry, garbage

dll = open_dll ("dlltest.dll")
entry = define_c_func (dll, "dll_entry_", {C_UINT}, C_UINT)
if entry = -1 then
    abortErr( "Function dll_entry not found" )
end if

garbage = c_func (entry,{5})
printf (1,"here is the value of 5+5 is %08x", garbage )





WinMain( Window1,Normal )
--this program has 33 lines without including this line. If there is a
discrepancy please send this file zipped to Judith.


Note: In order to make this find the function, I had to append a _ to the name.

Here is what happens when it is run:
A Console is generated by C:\EUPHORIA\bin\exw.exe

here is the value of 5+5 is 04000008

Note: global constant C_CHAR = #01000001,
                   C_UCHAR = #02000001,
                   C_SHORT = #01000002,
                  C_USHORT = #02000002,
                     C_INT = #01000004,
                    C_UINT = #02000004,

It seems as if the C_UINT value is being passed and not what I pass in c_proc.

Please tell me what I am doing wrong?
Thanks.

new topic     » topic index » view message » categorize

2. Re: Problem calling my C DLL from a IDE created source

Andrew Katz wrote:
> 
> I have spent all day trying to figure out why my Euphoria windows program
> cannot access my DLL. I have determined that in fact it does access it, but
> that the arguments are passed wrong. 

You might have to specify the CDECL calling convention.

 From the documentation for define_c_func():

    "On Windows, you can add a '+' character as a prefix to the 
     function name. This indicates to Euphoria that the function 
     uses the cdecl calling convention. By default, Euphoria assumes 
     that C routines accept the stdcall convention."

i.e.

    entry = define_c_func (dll, "+dll_entry_", {C_UINT}, C_UINT)

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

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

3. Re: Problem calling my C DLL from a IDE created source

Robert Craig wrote:
> 
> Andrew Katz wrote:
> > 
> > I have spent all day trying to figure out why my Euphoria windows program
> > cannot access my DLL. I have determined that in fact it does access it, but
> > that the arguments are passed wrong. 
> 
> You might have to specify the CDECL calling convention.
> 
>  From the documentation for define_c_func():
> 
>     "On Windows, you can add a '+' character as a prefix to the 
>      function name. This indicates to Euphoria that the function 
>      uses the cdecl calling convention. By default, Euphoria assumes 
>      that C routines accept the stdcall convention."
> 
> i.e.
> 
>     entry = define_c_func (dll, "+dll_entry_", {C_UINT}, C_UINT)
> 
> Regards,
>    Rob Craig
>    Rapid Deployment Software
>    <a href="http://www.RapidEuphoria.com">http://www.RapidEuphoria.com</a>

Adding the + had no effect. Should I try to compile the EUPHORIA language
myself and try to debug it?

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

4. Re: Problem calling my C DLL from a IDE created source

Andrew Katz wrote:
> Adding the + had no effect. Should I try to compile the EUPHORIA language
> myself and try to debug it?

Sure, if you feel up to it. I don't think you'll find
a bug in Euphoria, but you might understand the calling
conventions better.

I vaguely recall that Watcom does not implement the
CDECL calling convention exactly according to the standard.
There might be a problem with return values from the .dll. 
My memory on this is a bit hazy. Perhaps you should try to use 
the STDCALL convention in your .dll, and see if that works.
Or try the Borland C/C++ compiler. (Certainly you can't link
with C++ routines without doing some extra work that Matt Lewis
has figured out.)

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

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

5. Re: Problem calling my C DLL from a IDE created source

Andrew Katz wrote:

[snip]

> Adding the + had no effect. Should I try to compile the EUPHORIA language
> myself and try to debug it?

Hi Andrew,

Your C test code:

-- #if defined(__cplusplus)
-- #define EXPORTED extern "C" __declspec( dllexport )
-- #else
-- #define EXPORTED __declspec( dllexport )
-- #endif

-- EXPORTED int dll_entry( int arg )
-- {
--      return (arg + arg);
-- }

is just equal the following Euphoria code:

global function dll_entry(integer x)
  return x+x
end function  


I've translated it using ecw.exe with
-wat -dll options and compiled with OW 1.4

Resulting Dll works Ok for me here, your test
program prints 00000010.

So I think, why not go this way?

DLL is yours one, you have C code,
Euphoria code is simple ...

Why not?

Then, maybe to compile your C code of your Dll
with options of make.bat, generated by ecw.exe?

I'm not a specialist in C/C++, so just my $0.02.

Regards,
Igor Kachan
kinz at peterlink.ru

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

6. Re: Problem calling my C DLL from a IDE created source

Andrew Katz wrote:
> 
> I have spent all day trying to figure out why my Euphoria windows program
> cannot access my DLL. I have determined that in fact it does access it, but
> that the arguments are passed wrong. So, I made a test case for this forum.
> 
> Here is my C code compiled with the Watcom C compiler and linked to a
> Win32 NT DLL:
> 
> #if defined(__cplusplus)
> #define EXPORTED extern "C" __declspec( dllexport )
> #else
> #define EXPORTED __declspec( dllexport )
> #endif
> 
> 
> EXPORTED int dll_entry( int arg )
> {
> 	return (arg + arg);
> }
> 
> ------------
> 
> Here is the code from the IDE:
> 
> }}}
<eucode>
> --  code generated by Win32Lib IDE v0.22.0 Build Dec-16-2006
> 
> constant TheProgramType="exw" 
>  
> include Win32lib.ew
> without warning
> 
>
> --------------------------------------------------------------------------------
> --  Window Window1
> constant Window1 = createEx( Window, "Window1", 0, Default, Default, 400, 300,
> 0, 0 )
> ---------------------------------------------------------
>
> --------------------------------------------------------------------------------
> -- Test code in Window1 general
> 
> include dll.e -- this is for calling the dll written in C
> 
> atom dll
> integer entry, garbage
> 
> dll = open_dll ("dlltest.dll")
> entry = define_c_func (dll, "dll_entry_", {C_UINT}, C_UINT)
> if entry = -1 then
>     abortErr( "Function dll_entry not found" )
> end if
> 
> garbage = c_func (entry,{5})
> printf (1,"here is the value of 5+5 is %08x", garbage )
> 
> 
> WinMain( Window1,Normal )
> --this program has 33 lines without including this line. If there is a
> discrepancy please send this file zipped to Judith.
> </eucode>
{{{

> 
> Note: In order to make this find the function, I had to append a _ to the
> name.
> 
> Here is what happens when it is run:
> A Console is generated by C:\EUPHORIA\bin\exw.exe
> 
> here is the value of 5+5 is 04000008
> 
> Note: global constant C_CHAR = #01000001,
>                    C_UCHAR = #02000001,
>                    C_SHORT = #01000002,
>                   C_USHORT = #02000002,
>                      C_INT = #01000004,
>                     C_UINT = #02000004,
> 
> It seems as if the C_UINT value is being passed and not what I pass in c_proc.
> 
> Please tell me what I am doing wrong?
> Thanks.

I fixed this as follows:

The C program is:

int __stdcall __export _dll_entry( int arg )
{
	return (arg + arg);
}

And the change to the EU code is one line:

entry = define_c_func (dll, "__dll_entry@4", {C_UINT}, C_UINT)

-----------------

I do think this is a very strange way of doing things.
For example, why does not dll_entry by itself work?

It is important to realize that this was just a test case. I have a long C
procedure which I want to call and not rewrite.

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

7. Re: Problem calling my C DLL from a IDE created source

Andrew Katz wrote:
> I fixed this as follows:
> 
> The C program is:
> 
> int __stdcall __export _dll_entry( int arg )
> {
> 	return (arg + arg);
> }
> 
> And the change to the EU code is one line:
> 
> entry = define_c_func (dll, "__dll_entry@4", {C_UINT}, C_UINT)
> 
> -----------------
> 
> I do think this is a very strange way of doing things.
> For example, why does not dll_entry by itself work?

Windows dll's and the multiple C calling conventions are 
needlessly complicated and poorly documented, and aren't
fully compatible from one C compiler to the next.
Unfortunately Euphoria has to be able to interface
with these things. I think they add the "@4" part so
the C linker will know how many bytes of arguments
are to be passed.

> It is important to realize that this was just a test case. I have a long C
> procedure which I want to call and not rewrite.

You've won more than half the battle just by getting the interface
to work. What you do inside your C routine is your business
and should be relatively easy.

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

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

8. Re: Problem calling my C DLL from a IDE created source

Andrew Katz wrote:
> 
> Andrew Katz wrote:
> > 
> > I have spent all day trying to figure out why my Euphoria windows program
> > cannot access my DLL. I have determined that in fact it does access it, but
> > that the arguments are passed wrong. So, I made a test case for this forum.
> > 
> > Here is my C code compiled with the Watcom C compiler and linked to a
> > Win32 NT DLL:
> > 
> > #if defined(__cplusplus)
> > #define EXPORTED extern "C" __declspec( dllexport )
> > #else
> > #define EXPORTED __declspec( dllexport )
> > #endif
> > 
> > 
> > EXPORTED int dll_entry( int arg )
> > {
> > 	return (arg + arg);
> > }
> > 
> > ------------
> > 
> > Here is the code from the IDE:
> > 
> > }}}
<eucode>
> > --  code generated by Win32Lib IDE v0.22.0 Build Dec-16-2006
> > 
> > constant TheProgramType="exw" 
> >  
> > include Win32lib.ew
> > without warning
> > 
> >
> > --------------------------------------------------------------------------------
> > --  Window Window1
> > constant Window1 = createEx( Window, "Window1", 0, Default, Default, 400,
> > 300, 0, 0 )
> > ---------------------------------------------------------
> >
> > --------------------------------------------------------------------------------
> > -- Test code in Window1 general
> > 
> > include dll.e -- this is for calling the dll written in C
> > 
> > atom dll
> > integer entry, garbage
> > 
> > dll = open_dll ("dlltest.dll")
> > entry = define_c_func (dll, "dll_entry_", {C_UINT}, C_UINT)
> > if entry = -1 then
> >     abortErr( "Function dll_entry not found" )
> > end if
> > 
> > garbage = c_func (entry,{5})
> > printf (1,"here is the value of 5+5 is %08x", garbage )
> > 
> > 
> > WinMain( Window1,Normal )
> > --this program has 33 lines without including this line. If there is a
> > discrepancy please send this file zipped to Judith.
> > </eucode>
{{{

> > 
> > Note: In order to make this find the function, I had to append a _ to the
> > name.
> > 
> > Here is what happens when it is run:
> > A Console is generated by C:\EUPHORIA\bin\exw.exe
> > 
> > here is the value of 5+5 is 04000008
> > 
> > Note: global constant C_CHAR = #01000001,
> >                    C_UCHAR = #02000001,
> >                    C_SHORT = #01000002,
> >                   C_USHORT = #02000002,
> >                      C_INT = #01000004,
> >                     C_UINT = #02000004,
> > 
> > It seems as if the C_UINT value is being passed and not what I pass in
> > c_proc.
> > 
> > Please tell me what I am doing wrong?
> > Thanks.
> 
> I fixed this as follows:
> 
> The C program is:
> 
> int __stdcall __export _dll_entry( int arg )
> {
> 	return (arg + arg);
> }
> 
> And the change to the EU code is one line:
> 
> entry = define_c_func (dll, "__dll_entry@4", {C_UINT}, C_UINT)
> 
> -----------------
> 
> I do think this is a very strange way of doing things.
> For example, why does not dll_entry by itself work?
> 
> It is important to realize that this was just a test case. I have a long C
> procedure which I want to call and not rewrite.


Andrew,

When you have lots of legacy C code and you don't want to start inserting
Windows dynamic-link nonsense such as declspecs, EXPORTED or even write export
files, then the easiest way to go is to use MingW, the GCC port for Windows.

Creating a Windows DLL in MingW is as easy as writing C
code without any Windows dynamic link keywords and then using a command-line
which looks like this:

gcc -Wall -shared -Wl,--export-all-symbols -o <your_dll_name>.dll
<your_c_file>.c

(-Wall is optional, it is used to report all warnings)

MingW's generated interface code does not appear to be mangled, unlike
what you're experiencing with Watcom.

I used GCC / MingW 3.4.5 and could easily compile your example and call it
from Euphoria.

The only modification I made to your example was change this line:

entry = define_c_func (dll, "dll_entry", {C_UINT}, C_UINT)

to this:

entry = define_c_func (dll, "+dll_entry", {C_UINT}, C_UINT)


HTH!

RaGo

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

Search



Quick Links

User menu

Not signed in.

Misc Menu