compileIt for revolution?
Alex Tweedly
alex at tweedly.net
Wed Jun 22 19:15:09 EDT 2005
Derek Bump wrote:
> If one who knows C and could figure out some sort of Transcript
> wrapper, then it would be possible. There are many freeware and
> public domain compilers out there, but finding one that successfully
> compiles DLLs for Revolution is seemingly difficult. I've been trying
> for a few months now, but with my limited knowledge of C I end up
> running into errors.
>
> I am working on this project, but the *confusing* Externals SDK
> doesn't help. It's pretty bad when I've used about 10 different
> compilers (including MS Visual C) and I still can't get the samples to
> compile properly. But that's a whole different issue.
I had a lot of trouble getting it to work first time.
A week later, I had even more trouble getting it to work the second
time. (A sure sign that I hadn't really understood what I'd been doing
first time .... not even well enough for my detailed notes to make it
repeatable).
Third time was better ...... it only took me 4 tries and 2 false starts
tonight :-)
Now I can almost do it reliably.
The thing I kept getting wrong was understanding when the binding
happens, and what that implies.
The FAQ (in the "Externals" stack that came in the SDK says
> In order to bind to external libraries the "set externals to" function
> must be used. This tells the engine the library or multiple libraries
> that the engine should bind to the next time it starts up. Multiple
> libraries should be on separate lines.
What I now do (having got it wrong often enough, including right now
when I was writing down the step-by-step) is to start the stack up, set
the externals, save it, quit Rev. Restart Rev, open the stack, run the
script that sets externals again - then check that put the external of
this stack and put the externalFunctions of this stack give me what I
expect ....
SO you might want to retry your earlier efforts, taking extra care about
that step.
If it's not that .... read on.
Here's a step-by-step that now works reliably for me (even if I don't
properly understand one crucial step :-)
I use Bloodshed Dev C++ on Windows XP. I have version 4.9.9.1
(it's GPL - but that doesn't impose GPL restrictions on code compiled
with it).
0. Create a directory - keep things simple by making this a top-level
directory with no spaces in the name.
(That's probably unnecessary, but I had trouble with spaces in file
names. I think that was with one of the other compilers I tried earlier
- but I haven't gone back to change this and see if everything still
works ....)
00. unpack or unzip the Rev externals SDK into that directory.
1. make files this.c, this.h, this.def (see the end of the email for
their contents)
(why this.def ? and how did I figure out what goes into it ? far less
what to do with it ???
no idea, but it works now .....)
2. open Dev-c++
3. File / New / Project
Select DLL from the set of icons
Name the project "this"
Select C Project from the radio buttons
Click OK
In the file save dialog, make sure you select the directory where you
are doing this work (not the default), with the name as "this" (should
be default).
4. click on th "+" beside the Project in the left pane of the window
It should expand to show two files - dllmain.c and dllmain.h
5. For each of these, in turn, right click on it, select "Remove File"
(and say "no" to saving it).
6. Right click on the Project, select "Add to Project" and in the file
dialog select this.c
7. Repeat 6, selecting XCmdGlue.c
8. Menu select Project / Project Options .... select the Tab for
"Parameters"
Go to the 3rd column (Linker) and add to the end of the existing line "
--def this.def" (without the quotes)
The line should now read
--no-export-all-symbols --add-stdcall-alias --def this.def
and click "OK"
9. Menu select Execute / Compile
You'll see a dialog that shows "compiling this.c", then "compiling
XCmdGlue.c", then "Linking this.dll"
Check the log (select the "Log" tab to see it). If it all looks OK,
check that you now have a this.dll file
10. Start Rev, create a new main stack, add one button and one field.
Make the button script be
> on mouseUp
> put the effective filename of this stack into mVar
> set the itemDel to "/"
> put "this.dll" into item -1 of mVar
> set the externals of this stack to mVar
>
> put xname() into field "Field"
> end mouseUp
save it, and then click the button.
I think this will fail first time - you need to close the stack and
re-open it for the binding to take effect.
See above - I actually save it, exit Rev, etc. Probably unnecessary,
but I had so much trouble from 'accidental success' the first time I
tried all this, and couldn't repeat it second time, that I am just
paranoid .....
With any luck, you now have a working stack+external.
So now when you try what you want to do, and it doesn't work, you have a
base-line that you can compare against.
If you don't have luck, email me off-list and I'll send you all the
files involved from my system, and you can re-create the steps seeing
what differs. I did this, comparing file sizes of the binaries, at one
point, to discover that I was including the wrong .def file).
this.c
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> #include "XCmdGlue.h"
> #include "this.h"
>
> /*
> * This global table has one entry per XCMD/XFCN.
> * The first entry is the name of the handler
> * The second entry is the type (XCOMMAND or XFUNCTION)
> * The third entry is a space for the atom (used by the engine)
> * The fourth entry is the name of the 'C' function to call
> * The fifth entry is a callback called if the user aborts
> * Note that the last entry in the table is a NULL entry
> * which is used to measure the size of the table.
> */
>
> Xternal Xtable[] = {
> {"xname", XFUNCTION, 0, XGetName, XCabort},
> {"", XNONE, 0, NULL, NULL}
> };
>
>
> /*
> * This string identifies this external to the engine
> */
> char Xname[] = "runrev externals";
>
> void XCabort()
> {
> fprintf(stderr, "external abort");
> }
>
>
> void XGetName(char *args[], int nargs, char **retstring, Bool *pass,
> Bool *error)
> {
>
> *pass = False; // don't pass the command up the chain
> *error = False; // call was successful
> *retstring = istrdup ("this is my name");
> }
this.h
>
> #ifdef __STDC__
> extern void XGetName(char *args[], int nargs, char **retstring, Bool
> *pass, Bool *error);
>
> #else
>
> extern void XGetName();
>
> #endif
>
> extern void XCabort();
> extern Xternal Xtable[];
> extern char Xname[];
this.def
> LIBRARY external
> EXPORTS getXtable
>
(I rather suspect that first line should be
LIBRARY this
I think this is an accidental artifact of the sample being called
external.h - but have no clue how to tell. Changing it doesn't appear to
have any effect).
--
Alex Tweedly http://www.tweedly.net
--
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.323 / Virus Database: 267.7.8/22 - Release Date: 17/06/2005
More information about the use-livecode
mailing list