1. Machine level exception with define_c_func()

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

new topic     » topic index » view message » categorize

2. Re: Machine level exception with define_c_func()

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.

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

3. Re: Machine level exception with define_c_func()

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"

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

4. Re: Machine level exception with define_c_func()

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

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

5. Re: Machine level exception with define_c_func()

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

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

6. Re: Machine level exception with define_c_func()



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

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

7. Re: Machine level exception with define_c_func()

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"

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

8. Re: Machine level exception with define_c_func()

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

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

9. Re: Machine level exception with define_c_func()

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

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

Search



Quick Links

User menu

Not signed in.

Misc Menu