1. Machine level exception with define_c_func()
- Posted by Craig Welch <craig at singmail.com> Dec 09, 2005
- 594 views
I don't know C, but I'm trying to interface with a DLL from http://www.jafsoft.com/detagger/ to strip html leaving clean text. To start with, I'm trying just to allocate resources and deallocate them, without trying anything else. The two APIs are referenced as follows: DLL_DECLARE CONVERTER_Allocate (); DLL_DECLARE CONVERTER_Free (long &Handle); I've written the following code: <EUCODE> include dll.e atom dll_handle, CONVERTER_Allocate,CONVERTER_Free object result dll_handle = open_dll("c:\\euphoria\\include\\detagger_eval.dll") -- Allocate some resources: CONVERTER_Allocate = define_c_proc(dll_handle, "CONVERTER_Allocate", {}) c_proc(CONVERTER_Allocate, {}) -- Free the resources CONVERTER_Free = define_c_func(dll_handle, "CONVERTER_Free", {C_INT}, C_SHORT) result = c_func(CONVERTER_Free, {CONVERTER_Allocate}) </EUCODE> The last statement fails with "A machine-level exception occurred during execution of this statement". Given that I've never used any C functions from Euphoria, my first assumption is that I've put coded the c_func() or define_c_func() statements wrongly. But I've gone over them and over, and tried different types of C variables ... without any success. Any thoughts? Thanks, -- Craig
2. Re: Machine level exception with define_c_func()
- Posted by mic <micol972 at gmail.com> Dec 09, 2005
- 565 views
Without knowing the details about this particular DLL, shouldn't the allocate function return a value (a pointer/handle to the resource), which also is the input parameter to Free. Right now you have the Allocate function as a procedure which pretty much makes it useless.
3. Re: Machine level exception with define_c_func()
- Posted by Al Getz <Xaxo at aol.com> Dec 09, 2005
- 567 views
Craig Welch wrote: > > I don't know C, but I'm trying to interface with a DLL from > <a > href="http://www.jafsoft.com/detagger/">http://www.jafsoft.com/detagger/</a> to > strip html leaving clean text. > > To start with, I'm trying just to allocate resources and deallocate > them, without trying anything else. > > The two APIs are referenced as follows: > > DLL_DECLARE CONVERTER_Allocate (); > > DLL_DECLARE CONVERTER_Free (long &Handle); > > I've written the following code: > > <font color="#330033"><EUCODE></font> > <font color="#0000FF">include </font><font color="#330033">dll.e</font> > <font color="#FF00FF">atom </font><font color="#330033">dll_handle, > CONVERTER_Allocate,CONVERTER_Free</font> > <font color="#FF00FF">object </font><font color="#330033">result</font> > <font color="#330033"></font> > <font color="#330033">dll_handle = open_dll(</font><font > color="#00A033">"c:\\euphoria\\include\\detagger_eval.dll"</font><font > color="#330033">)</font> > <font color="#330033"></font> > <font color="#FF0055">-- Allocate some resources:</font> > <font color="#330033">CONVERTER_Allocate = define_c_proc(dll_handle, > </font><font color="#00A033">"CONVERTER_Allocate"</font><font color="#330033">, > </font><font color="#993333">{}</font><font color="#330033">)</font> > <font color="#FF00FF">c_proc</font><font color="#330033">(CONVERTER_Allocate, > </font><font color="#993333">{}</font><font color="#330033">)</font> > <font color="#330033"></font> > <font color="#FF0055">-- Free the resources</font> > <font color="#330033">CONVERTER_Free = define_c_func(dll_handle, </font><font > color="#00A033">"CONVERTER_Free"</font><font color="#330033">, </font><font > color="#993333">{</font><font color="#330033">C_INT</font><font > color="#993333">}</font><font color="#330033">, </font> > <font color="#330033">C_SHORT)</font> > <font color="#330033">result = </font><font color="#FF00FF">c_func</font><font > color="#330033">(CONVERTER_Free, </font><font color="#993333">{</font><font > color="#330033">CONVERTER_Allocate</font><font color="#993333">}</font><font > color="#330033">)</font> > <font color="#330033"></EUCODE></font> > > The last statement fails with "A machine-level exception occurred during > execution of this statement". > > Given that I've never used any C functions from Euphoria, my first > assumption is that I've put coded the c_func() or define_c_func() > statements wrongly. But I've gone over them and over, and tried > different types of C variables ... without any success. > > Any thoughts? > > Thanks, > > -- > Craig > > Hi there Craig, The first step is to separate the two calls result = c_func(CONVERTER_Free, {CONVERTER_Allocate}) in one line to two lines each calling only one function. Doing this, it looks like CONVERTER_Allocate is not a valid resource object. Usually a resource allocator will return an object, and then you can pass that object to the resource free'er. For example... atom xa xa=Allocate() Free(xa) which for your code would look something like this: CONVERTER_Allocate = define_c_func(dll_handle, "CONVERTER_Allocate", {} ,C_POINTER) CONVERTER_Free = define_c_func(dll_handle, "CONVERTER_Free", {C_POINTER}, C_LONG) atom ob ob=c_func(CONVERTER_Allocate,{}) result=c_func(CONVERTER_Free, {ob}) There's also a chance the free'er can be defined as a procedure instead of a function. Take care, Al And, good luck with your Euphoria programming! My bumper sticker: "I brake for LED's"
4. Re: Machine level exception with define_c_func()
- Posted by Craig Welch <craig at singmail.com> Dec 10, 2005
- 587 views
Al Getz wrote: >>The last statement fails with "A machine-level exception occurred during >>execution of this statement". >> >>Given that I've never used any C functions from Euphoria, my first >>assumption is that I've put coded the c_func() or define_c_func() >>statements wrongly. But I've gone over them and over, and tried >>different types of C variables ... without any success. >> ><snip> > >which for your code would look something like this: > >CONVERTER_Allocate = define_c_func(dll_handle, "CONVERTER_Allocate", {} >,C_POINTER) >CONVERTER_Free = define_c_func(dll_handle, "CONVERTER_Free", {C_POINTER}, >C_LONG) > > >atom ob >ob=c_func(CONVERTER_Allocate,{}) >result=c_func(CONVERTER_Free, {ob}) > >There's also a chance the free'er can be defined as a procedure instead of >a function. > Thanks Al, I've done that, and still get the failure "A machine-level exception occurred during execution of this statement" I've also tried changing CONVERTER_Free to a procedure. Time to ask the DLL owner, or any more thoughts from the Euphoria end? I'm using an evaluation copy of the DLL, so I don't know that the owner will want to put any effort into supporting me at this stage. If I can get it working, I'm quite happy to pay him for a licence. -- Craig
5. Re: Machine level exception with define_c_func()
- Posted by DGuy <dguy-o000 at usa.net> Dec 10, 2005
- 594 views
- Last edited Dec 11, 2005
As I was putting the finishing touches on my original message, I realized why Euphoria COULD NOT work directly with the DLL: the handle passed to CONVERTER_Free needs to be passed by reference. Euphoria can pass-by-value and pass a pointer, but can not pass-by-reference. If CONVERTER_Free where declared like this: DLL_DECLARE CONVERTER_Free(long Handle); // pass handle by value -- OR -- DLL_DECLARE CONVERTER_Free(long *Handle); // pass pointer to handle Euphoria could work directly with it. But since it's decalred as: DLL_DECLARE CONVERTER_Free(long &Handle); // '&' means pass by reference Euphoria can not call it directly. You would need to write a thin C-wrapper around the DLL that would translate the calls from Euphoria-to-DLL and from DLL-to-Euphoria. Though the below code WILL NOT WORK, due the pass-by-reference requierment, I decided to pass it along any way in case you where curious. HTH --------- Origin Message Below ---------- Taking a brief look at the DLL documentaion and header file. In the header file I see: #define DLL_DECLARE __declspec(dllexport) long __stdcall DLL_DECLARE CONVERTER_Allocate(); // returns non-zero Handle if succeeds DLL_DECLARE CONVERTER_Free(long &Handle); //return 1 if handle is valid, 0 if invalid I would link to the functions like this: [eucode] include dll.e atom dll_handle integer CONVERTER_Allocate, CONVERTER_Free dll_handle = open_dll( "detagger_eval.dll" ) -- can add path as needed if dll_handle = 0 then puts( 1, "Could not open dll!\n" ) abort(1) end if CONVERTER_Allocate = define_c_func( dll_handle, "CONVERTER_Allocate", {}, C_LONG ) if CONVERTER_Allocate = -1 then puts( 1, "Could not find CONVERTER_Allocate!\n" ) abort(1) end if CONVERTER_Free = define_c_func( dll_handle, "CONVERTER_Allocate", {C_LONG}, C_LONG ) if CONVERTER_Free = -1 then puts( 1, "Could not find CONVERTER_Free!\n" ) abort(1) end if [/eucode] And call them like this: [eucode] atom handle handle = c_func( CONVERTER_Allocate, {} ) if handle = 0 then puts( 1, "Could not allocate converter object!\n" ) end if if not c_func( CONVERTER_Free, {handle} ) then -- <-- WILL NOT WORK!! 'handle' NEEDS TO BE PASSED BY REFERENCE !! puts( 1, "Invalid converter handle!\n" ) end if [/eucode] HTH
6. Re: Machine level exception with define_c_func()
- Posted by Bernie Ryan <xotron at bluefrog.com> Dec 10, 2005
- 584 views
- Last edited Dec 11, 2005
atom handle_ref handle_ref = allocate(4) poke4(handle_ref,handle) if not c_func( CONVERTER_Free, {handle_ref} ) then -- PASSED BY REFERENCE !! puts( 1, "Invalid converter handle!\n" ) end if
Bernie My files in archive: w32engin.ew mixedlib.e eu_engin.e win32eru.exw Can be downloaded here: http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan
7. Re: Machine level exception with define_c_func()
- Posted by Al Getz <Xaxo at aol.com> Dec 11, 2005
- 588 views
Bernie Ryan wrote: > > }}} <eucode> > atom handle_ref > handle_ref = allocate(4) > poke4(handle_ref,handle) > > if not c_func( CONVERTER_Free, {handle_ref} ) then -- PASSED BY REFERENCE !! > puts( 1, "Invalid converter handle!\n" ) > end if > </eucode> {{{ > > > Bernie > > My files in archive: > w32engin.ew mixedlib.e eu_engin.e win32eru.exw > > Can be downloaded here: > <a > href="http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan">http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan</a> Hi Bernie, Yeah i was going to say, "poke the dang ting into memory then" hee hee. Take care, Al And, good luck with your Euphoria programming! My bumper sticker: "I brake for LED's"
8. Re: Machine level exception with define_c_func()
- Posted by Craig Welch <craig at singmail.com> Dec 11, 2005
- 563 views
Bernie Ryan wrote: >if not c_func( CONVERTER_Free, {handle_ref} ) then -- PASSED BY REFERENCE !! > puts( 1, "Invalid converter handle!\n" ) >end if > Well that fixed the problem for me! Thanks DGuy for pointing out that my lack of understanding of the need for a handle, and my lack of realising that the '&' signified same. In fact, I had looked through Bernie's w32.engin beginners.txt a few days ago, when I started this project, as there are some notes there on C interfacing. I obviously didn't pay enough attention, because there is a paragraph there that describes conventions such as '&Handle'. Bernie, thanks for going to the trouble of adding that key bit of code that completely fixed the problem. Now the machine exception makes perfect sense to me, as I was giving the DLL a what it thought was a reference to memory that was completely invalid. I've done a few Euphoria projects now, and I think I'm beginning to get a better understanding of when I should just re-think and re-read to get the answer to a problem, and when I'm out of my depth and need to ask here. Every time I've asked here, I've had the right answer within a day or two, and my knowledge of programming (generally, not just Euphoria) has increased dramatically. The problem above helps validate my choice of Euphoria as the language in which to program. I'm sure glad I didn't choose one of the C variations! Thanks again, -- Craig
9. Re: Machine level exception with define_c_func()
- Posted by DGuy <dguy-o000 at usa.net> Dec 11, 2005
- 572 views
Bernie Ryan wrote: > > }}} <eucode> > atom handle_ref > handle_ref = allocate(4) > poke4(handle_ref,handle) > > if not c_func( CONVERTER_Free, {handle_ref} ) then -- PASSED BY REFERENCE !! > puts( 1, "Invalid converter handle!\n" ) > end if > </eucode> {{{ > Learn something new everyday! :) Thx