JRowe Posted April 15, 2010 Posted April 15, 2010 (edited) Python, Perl, Ruby, Free Basic and Java all have it... no reason why AutoIt shouldn't. I revisited some of my old topics, and then dug around a bit after the embedded c topic sparked my interest.I found TCC, which is a simple to use, small, and fast x86 c compiler. The aforementioned languages use it in libraries to compile c code during runtime, on the fly. There are two methods of using it which could be of interest: 'C Scripting' and using tccLib to generate code. I went with the latter, and compiled a dll per some instructions I found.I'll post the dll how-to if anyone's interested. You need MingW and the TCC source distribution.The dll is here. Docs are here.I don't know enough about how c works to understand how this works, but I'd like to give it a shot. It's my understanding that the following c code uses tcclib to generate/compile a function, then load it into memory, similar to the way a DLL function would be loaded. /* * Simple Test program for libtcc * * libtcc can be useful to use tcc as a "backend" for a code generator. */#include <stdlib.h>#include <stdio.h>#include <string.h>#include "libtcc.h"/* this function is called by the generated code */int add(int a, int <img src='http://www.autoitscript.com/forum/public/style_emoticons/<#EMO_DIR#>/sad.png' class='bbc_emoticon' alt=':(' />{ return a + b;}char my_program[] ="int fib(int n)\n""{\n"" if (n <= 2)\n"" return 1;\n"" else\n"" return fib(n-1) + fib(n-2);\n""}\n""\n""int foo(int n)\n""{\n"" printf(\"Hello World!\\n\");\n"" printf(\"fib(%d) = %d\\n\", n, fib(n));\n"" printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"" return 0;\n""}\n";int main(int argc, char **argv){ TCCState *s; int (*func)(int); void *mem; int size; s = tcc_new(); if (!s) { fprintf(stderr, "Could not create tcc state\n"); exit(1); } /* if tcclib.h and libtcc1.a are not installed, where can we find them */ if (argc == 2 && !memcmp(argv[1], "lib_path=",9)) tcc_set_lib_path(s, argv[1]+9); /* MUST BE CALLED before any compilation */ tcc_set_output_type(s, TCC_OUTPUT_MEMORY); if (tcc_compile_string(s, my_program) == -1) return 1; /* as a test, we add a symbol that the compiled program can use. You may also open a dll with tcc_add_dll() and use symbols from that */ tcc_add_symbol(s, "add", add); /* get needed size of the code */ size = tcc_relocate(s, NULL); if (size == -1) return 1; /* allocate memory and copy the code into it */ mem = malloc(size); tcc_relocate(s, mem); /* get entry symbol */ func = tcc_get_symbol(s, "foo"); if (!func) return 1; /* delete the state */ tcc_delete(s); /* run the code */ func(32); free(mem); return 0;}There is two way communication, where the dynamically compiled code is able to call a predefined function (add). In order to implement this in AutoIt, would I use DllCallbackRegister to intercept calls to add()? Or to register a pointer to the foo/func() symbol?The reverse also has its challenges.The order of events goes something like this: tcc_set_lib_path()tcc_set_output_type()tcc_compile_string()tcc_get_symbol()tcc_run(s, param1, param2)tcc_delete(s)Is there a need for libtcc.h in this setup, or can AutoIt and DllCall handle everything necessary and relevant?Anyhow, I'd love to get some feedback on how I'd get this working. It's a little over my head (and/or I'm up way too late,) but I see some potential here. It would be an easy, practical method of integrating c code directly into a script. This will be fun. Edited April 15, 2010 by JRowe [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center]
Richard Robertson Posted April 15, 2010 Posted April 15, 2010 AutoIt and DllCall can do everything as long as you know what you're doing.
Fulano Posted April 15, 2010 Posted April 15, 2010 Can it make me a sandwich?...Sorry, I couldn't resist. #fgpkerw4kcmnq2mns1ax7ilndopen (Q, $0); while ($l = <Q>){if ($l =~ m/^#.*/){$l =~ tr/a-z1-9#/Huh, Junketeer's Alternate Pro Ace /; print $l;}}close (Q);[code] tag ninja!
JRowe Posted April 16, 2010 Author Posted April 16, 2010 expandcollapse popup#include <Memory.au3> $dll = DllOpen("libtcc.dll") Func Add($iA, $iB) Return $iA + $iB EndFunc ;==>Add $myProgram = 'int fib(int n)' & @CRLF & _ '{'& @CRLF & _ ' if (n <= 2)'& @CRLF & _ ' return 1;'& @CRLF & _ ' else'& @CRLF & _ ' return fib(n-1) + fib(n-2);'& @CRLF & _ '}'& @CRLF & _ ''& @CRLF & _ 'int foo(int n)'& @CRLF & _ '{'& @CRLF & _ ' printf("Hello World!\n");'& @CRLF & _ ' printf("fib(%d) = %d\n", n, fib(n));'& @CRLF & _ ' printf("add(%d, %d) = %d\n", n, 2 * n, add(n, 2 * n));'& @CRLF & _ ' return 0;'& @CRLF & _ '}' Global $functionState Global $howDoIGetAFunctionPointer $result1 = DllCall($dll, "ptr:cdecl", "tcc_new") ConsoleWrite("Result 1 :" & @error & $result1[0] & @CRLF) $functionState = $result1[0] $result2 = DllCall($dll, "none:cdecl", "tcc_set_output_type", "ptr", $functionState, "int", 0) ConsoleWrite("Result 2 :" & @error & @CRLF) $result3 = DllCall($dll, "none:cdecl", "tcc_compile_string", "ptr", $functionState, "str", $myProgram) ConsoleWrite("Result 3 :" & @error & @CRLF) ;/* as a test, we add a symbol that the compiled program can use. ; You may also open a dll with tcc_add_dll() and use symbols from that */ ;tcc_add_symbol(s, "add", add); $result4 = DllCall($dll, "none:cdecl", "tcc_add_symbol", "ptr", $functionState, "str", "add", "ptr", $howDoIGetAFunctionPointer) ;?! ConsoleWrite("Result 4 :" & @error & @CRLF) $result5 = DllCall($dll, "int:cdecl", "tcc_relocate", "ptr", $functionState, "int", 0) ConsoleWrite("Result 5 :" & @error & @CRLF) $size = $result5[0] $mem = _MemGlobalAlloc($size) DllCall($dll, "none:cdecl", "tcc_relocate", "ptr", $functionState, "ptr", $mem) ConsoleWrite("Result 5.1 :" & @error & @CRLF) ;/* allocate memory and copy the code into it */ ;mem = malloc(size); ;tcc_relocate(s, mem); $result6 = DllCall($dll, "ptr:cdecl", "tcc_get_symbol", "ptr", $functionState, "str", "foo") ConsoleWrite("Result 6 :" & @error & @CRLF) $tccFunc = $result6[0] ConsoleWrite("Result 6.1 :" & $tccFunc & @CRLF) ;/* get entry symbol */ ;func = tcc_get_symbol(s, "foo"); ;if (!func) ; return 1; DllCall($dll, "none:cdecl", "tcc_delete", "ptr", $functionState) ConsoleWrite("Result 6.5 :" & @error & @CRLF) ;/* run the code */ ;func(32); _MemGlobalFree($mem) I think I've got it functioning. It's allocating a new state, setting the output parameter, compiling, assessing the size, allocating the space, and writing the compiled code into the allocated space. All without apparent errors on either side (tcc gives you debug output, as I discovered when i constructed the c code in a string.) Anyone want to take a stab at how I'd convert the $tccFunc pointer into a usable function? I'm thinking DllCallbackRegister could be used, but I don't know how. [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center]
wraithdu Posted April 16, 2010 Posted April 16, 2010 You need to be able to call the function pointer. So look at Ward's MemoryDll UDF, or if you don't need parameters, you might be able to use CallWindowProc to call the function. (Here's me hoping the AutoIt devs decide to let us call function pointers one day )
Kip Posted April 21, 2010 Posted April 21, 2010 This looks really cool. Inline C MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API.
JRowe Posted April 21, 2010 Author Posted April 21, 2010 I'm trying to get your 'call function by pointer' plugin to work, actually. I'd appreciate any time you spend on this. I'm thinking I need to use a different memory allocation function, and there's probably some more setup needed from the dll side... but I'll have to wait for the weekend to spend more time on this. [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center]
Kip Posted April 21, 2010 Posted April 21, 2010 How did you compile the DLL? MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API.
JRowe Posted April 21, 2010 Author Posted April 21, 2010 (edited) I used MSYS , per this article, using the following command/s:gcc -O2 -shared -Wall -Wl,--export-all-symbols \ -mpreferred-stack-boundary=2 \ -march=i386 -falign-functions=0 -fno-strict-aliasing \ -DTCC_TARGET_PE -DLIBTCC -o libtcc.dll tcc.c Edited April 21, 2010 by JRowe [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center]
Kip Posted May 27, 2010 Posted May 27, 2010 Could someone tell me how to use this library with Visual C++ 2008? If I include libtcc.c directly into my project the only error it gives is: fatal error C1083: Cannot open include file: 'config.h': No such file or directory Seems simple enough, but I don't know how to fix it. I found a precompiled static library on the internet: http://sourceforge.net/projects/tinycc-win32/ When I include the header file and add TinyCC-Win32-lib.lib to the linker, I get a bunch of redefinitions: Error 1 error LNK2005: _malloc already defined in LIBCMTD.lib(dbgmalloc.obj) MSVCRTD.lib Error 2 error LNK2005: _exit already defined in LIBCMTD.lib(crt0dat.obj) MSVCRTD.lib Error 3 error LNK2005: _sprintf already defined in LIBCMTD.lib(sprintf.obj) MSVCRTD.lib Error 4 error LNK2005: _free already defined in LIBCMTD.lib(dbgfree.obj) MSVCRTD.lib Error 5 error LNK2005: __errno already defined in LIBCMTD.lib(dosmap.obj) MSVCRTD.lib Error 6 error LNK2005: _strrchr already defined in LIBCMTD.lib(strrchr.obj) MSVCRTD.lib Error 7 error LNK2005: _memmove already defined in LIBCMTD.lib(memmove.obj) MSVCRTD.lib Error 8 error LNK2005: _strtoul already defined in LIBCMTD.lib(strtol.obj) MSVCRTD.lib Error 9 error LNK2005: _strchr already defined in LIBCMTD.lib(strchr.obj) MSVCRTD.lib Error 10 error LNK2005: _fclose already defined in LIBCMTD.lib(fclose.obj) MSVCRTD.lib Error 11 error LNK2005: _fputc already defined in LIBCMTD.lib(fputc.obj) MSVCRTD.lib Error 12 error LNK2005: _fwrite already defined in LIBCMTD.lib(fwrite.obj) MSVCRTD.lib Error 13 error LNK2005: _strncmp already defined in LIBCMTD.lib(strncmp.obj) MSVCRTD.lib Error 14 error LNK2005: _strtol already defined in LIBCMTD.lib(strtol.obj) MSVCRTD.lib Error 15 error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj) MSVCRTD.lib Error 16 error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in LIBCMTD.lib(typinfo.obj) MSVCRTD.lib Error 18 fatal error LNK1169: one or more multiply defined symbols found C:\Documents and Settings\HP_Administrator\Mijn documenten\Visual Studio 2008\Projects\LibCC\Debug\LibCC.exe 1 Does anyone know how to do this? MailSpons: Fake SMTP server for safe email testing Dutch postcode & address API.
monoceres Posted May 27, 2010 Posted May 27, 2010 My first guess when looking at that output would be to specify the /NODEFAULTLIB option. Broken link? PM me and I'll send you the file!
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now