Re: Euphoria DLLs

new topic     » goto parent     » topic index » view thread      » older message » newer message

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

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu