Re: Euphoria DLLs
- Posted by Elliott Sales de Andrade <quantum_analyst at hotmail.com> Apr 27, 2003
- 509 views
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