1. Problem calling my C DLL from a IDE created source
- Posted by Andrew Katz <Akatz712 at gmail.com> Mar 07, 2007
- 548 views
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.
2. Re: Problem calling my C DLL from a IDE created source
- Posted by Robert Craig <rds at RapidEuphoria.com> Mar 07, 2007
- 500 views
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
3. Re: Problem calling my C DLL from a IDE created source
- Posted by Andrew Katz <Akatz712 at gmail.com> Mar 07, 2007
- 502 views
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?
4. Re: Problem calling my C DLL from a IDE created source
- Posted by Robert Craig <rds at RapidEuphoria.com> Mar 07, 2007
- 512 views
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
5. Re: Problem calling my C DLL from a IDE created source
- Posted by Igor Kachan <kinz at peterlink.ru> Mar 07, 2007
- 514 views
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
6. Re: Problem calling my C DLL from a IDE created source
- Posted by Andrew Katz <Akatz712 at gmail.com> Mar 08, 2007
- 490 views
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.
7. Re: Problem calling my C DLL from a IDE created source
- Posted by Robert Craig <rds at RapidEuphoria.com> Mar 08, 2007
- 517 views
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
8. Re: Problem calling my C DLL from a IDE created source
- Posted by RaGo <ramesh_gopal at hotmail.com> Mar 09, 2007
- 501 views
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