Practice C App Embedded in Scripting Language?

This is a discussion on Practice C App Embedded in Scripting Language? within the C Programming forums, part of the General Programming Boards category; got a hello world running with apache/cgi, now I want to embed a C app in php/perl or python. which ...

  1. #1
    Registered User
    Join Date
    Jan 2012
    Posts
    14

    Practice C App Embedded in Scripting Language?

    got a hello world running with apache/cgi, now I want to embed a C app in php/perl or python. which of those does C integrate best with?

    I'd like to use the C app to update text in terminal/vim, which would update cgi/web page in real time. or, I'm open to any app having to do with systems data, etc...anything but forms.

    thanks in advance for advice and/or suggestions as to how to get started.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by pavl View Post
    got a hello world running with apache/cgi, now I want to embed a C app in php/perl or python. which of those does C integrate best with?
    I'm sure python has a decent C interface, I dunno about php. Perl is very C based, and there are various ways to incorporate one into the other.

    Perl's backbone is XS modules, which are written in C. I've never done this directly (write an .xs source file), but for about 6 months now I've been using Inline::C with a big perl project and I think it's the greatest thing since chocolate + peanut butter:

    Inline::C - search.cpan.org

    Inline actually supports a bunch of other languages too. It's drop dead simple, here's an example .pl:

    Code:
    #!/usr/bin/perl
    use strict;
    use warnings FATAL => qw(all);
    
    use Inline 'C' => Config => 
    	CCFLAGS => '-Wall -O2 -g -std=c99',
    	CLEAN_AFTER_BUILD => 1;
    #	LIBS => '-lwhatever';  <-- link in C libs
    use Inline 'C';
    
    my $hash_ref = demo("Inline C!", [ "one", "two", "three" ]);
    while (my ($k, $v) = each (%{$hash_ref})) {
    	print "$k $v\n";
    }
    
    __DATA__
    __C__
    HV *demo (char *str, SV *ref) {
    	puts(str);
    	AV *array = (AV*)SvRV(ref);
    	int i, len, sz = av_len(array);
    	HV *rv = newHV();
    	SV **field;
    	char *key;
    	for (i = 0; i <= sz; i++) {
    		field = av_fetch(array, i, 0);
    		key = SvPV(*field , len);
    		hv_store(rv, key, len, newSViv(i+1), 0);
    	}
    	return rv;
    }
    This is probably nicer and easier if you use an editor or IDE which can toggle the file type back and forth for syntax highlighting (such as vim).

    When run Inline creates an .xs file and compiles the module; it leaves that stuff in a directory (_Inline) wherever the script is run. If you haven't changed anything in the _C_ section, the library is not re-compiled each run, which would make a big difference with cgi.

    If the C compiler throws an error, the errors reported are actually from the .xs file like this:
    Code:
    test_pl_7f28.xs: In function ‘demo’:
    test_pl_7f28.xs:12:9: error: request for member ‘sv_flags’ in something not a structure or union
    "test_pl_7f28.xs" will be in _Inline/build/test_pl_7f28, and the line reference will match code from your .pl file, so you refer to that but correct the .pl file. Apparently, you can rip that .xs file* out and create a proper XS module with it, I have not bothered yet as Inline seems like a much nicer system anyway. But I have (on linux) pulled the complied shared object library (.so) from the _Inline/lib/auto/blah_blah directory, renamed it, and put it into the compiler library path then linked to it in other perl scripts using the 'LIBS' param to Inline. That is very nice because writing a C lib using the perl API in pure C, using a C compiler directly, is not recommended by me or probably anyone else, lol. Which is kind of a shame because the perl API is actually a great general purpose dynamic complex data structure library.

    All you need for the basics of the API is in perlguts:
    perlguts - perldoc.perl.org

    You can debug the C parts by running the debugger on the perl executable (eg, "gdb perl"), then running the script as an argument to perl (so in gdb, "run myscript.pl").

    * by default, those are actually deleted if the build succeeds unless you set CLEAN_AFTER_BUILD to 0.

    I'd like to use the C app to update text in terminal/vim, which would update cgi/web page in real time. or, I'm open to any app having to do with systems data, etc...
    Cgi is not persistent, so in fact the only way to do something like that is a completely separate application which updates a file or database.

    If you like perl, C, and apache, I'd look into mod_perl and the apache C API eventually. If you like php's "embedded in html" style but prefer perl generally, you might like mason:

    Mason HQ: Welcome to Mason

    Which allows you to embed perl in html exactly the same way (it's actually more flexible than php IMO). Mason and mod_perl are much higher performance than cgi because they launch an interpreter to compile & load* all the perl stuff when you start apache, which then remains part of apache.

    * perl actually uses a two step interpreter like python or java, but the bytecode produced is not written to or read from a disk file, so must be rebuilt each run.
    Last edited by MK27; 01-15-2012 at 12:55 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Jan 2012
    Posts
    14
    thanks MK27! I will be returning to your response more than once...you're making a case for Perl Inline::C. closest thing in PHP seems to be using Zend.

    so mod_perl gives better performance than cgi with Apache...what does apache C api do? I read a little about that but unclear as to what it's doing...

    your post makes me think about turning towards Perl...looking at your coding talent I'm guessing you prefer Perl over Php. Is html a pain with Perl?

    If you have a minute, would you please explain what your code is doing? I can see the Inline part, then a hash table, then calling C data/string (but I'm not sure from where as no external file listed)...and what's the HV *rv? how is the hash table relevant to the C data? thanks, I'm learning.
    Last edited by pavl; 01-15-2012 at 02:42 PM.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Yeah, I prefer perl over php, altho perl is a tougher nut to crack initially. WRT HTML/HTTP, it has at least the features php has, but there is no one dominant path -- there's cgi, various libs like Mason for php-esque embeddedness, mod_perl, various stand-alone perl servers. The drawback to all that heterogeneity is finding your way around.

    If you have a minute, would you please explain what your code is doing? I can see the Inline part, then a hash table, then calling C data/string (but I'm not sure from where as no external file listed)...and what's the HV *rv? how is the hash table relevant to the C data?
    All the stuff below the __C__ is pure C code, but it uses the perl API, which are the non-standard types and related functions (those are documented in perlguts). So demo() takes a char* and an SV*. Basic types are automatically converted, eg, perl string -> char*, so "Inline C!" from the call:

    Code:
    my $hash_ref = demo("Inline C!", [ "one", "two", "three" ]);
    is "str" in demo():

    Code:
    HV *demo (char *str, SV *ref) {
    An SV* is a pointer to a perl scalar type, which includes references -- [ "one", "two", "three" ] -- is a reference to an anonymous array.

    An HV* is a pointer to a perl hash (so when returned, it's a hash reference). I use "rv" for return value variables a lot. So the demo just constructs a hash, using the values from the array submitted as keys and assigning them the array index as a value, so the output is:

    Code:
    Inline C!
    three 3
    one 1
    two 2
    Since perl hashes are not sorted.

    You can also create and return objects. Inline is great for writing fast functions and doing the kind of low level things C is good for, like byte by byte single pass parsing.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Jan 2012
    Posts
    14
    so you have pointers in C sections because it's in C yes? (as in perl does not require pointers.) does perl scalar type refer to array values can be either integers or characters and you substitute for either one later in your code (three 2 one 1 etc.)?

    what is single pass parsing? and would that apache c api be used to prevent memory leaks on the server? thanks again for your detailed responses...having a coder break it down gives perspective--also bookmarked that c tutorial in your signature.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by pavl View Post
    so you have pointers in C sections because it's in C yes? (as in perl does not require pointers.)
    Perl does have references, which are implemented (the perl interpreter is written in C) with C pointers, and the easiest way to use the perl <-> C API is to use references/pointers. In C, you cannot return any complex data structure except via a pointer; demo() returns a pointer and so on the perl side this is a reference. In pure perl, you can return arrays and hashes as copies (aka, by value); but while it depends on the extent of the data and its fate, references are still generally more efficient (so nb, perl object notation is all references, like obj->method). Anyway: the pure perl return-a-copy mechanism is accomplished with a global stack; this is the same stack unwound in subrountines, which is why perl doesn't use parameter lists:

    Code:
    #!/usr/bin/perl
    use strict;
    use warnings FATAL => qw(all);
    
    sub eg {
    	while (my $arg = shift) {
    		print "$arg\n";
    	}
    }
    
    eg('one', 'two', 'three');
    That stack is not accessible via a C parameter list and you cannot put stuff on it via a return value, but you can manipulate it using Inline with some macros:

    Inline::C - search.cpan.org

    does perl scalar type refer to array values can be either integers or characters and you substitute for either one later in your code (three 2 one 1 etc.)?
    Scalars in perl are singular values (eg: "hello world", or 900), including references (which again, are actually pointers, altho in pure perl you don't call them that or need to understand this). The SvRV() macro used in demo() is used to fetch the pointer to the AV type (AV = Array Value, Sv = Scalar value, RV = Reference Value; so this is a scalar value containing a reference to an array, which is a C typedef. The "RV" is exactly the same as any other C pointer, containing an address. The perlguts page gets into all this).

    what is single pass parsing?
    When you take a data source and parse the input byte by byte on a single pass -- ie, you don't load the data into a buffer and go thru it several times extracting various things, possibly based on the information retrieved on a previous pass. Single pass parsing is limited in what it can achieve -- eg, turing completeness cannot be implemented in a single pass. But it is fine for a lot of simpler protocols (such as HTML or HTTP) and is obviously more efficient than rewinding, using multiple buffers, making multiple passes, etc. C is ideal for that, but higher level languages (such as perl) make it awkward due to the amount of abstraction involved with the types.

    and would that apache c api be used to prevent memory leaks on the server?
    Memory leaks are a very serious issue with apache or any web server because ideally, the server runs indefinitely -- for days, weeks, months. CGI is low performance because it simply pipes thru a separate, short lived process. This means there is the processor overhead of instantiating the process (hence, low performance). However, it also means that any memory leaked by the process is irrelevant.

    The apache C api can be used to create apache modules, which are built into the server, so persist for its lifetime, which makes memory leaks a major concern. However, they deliver higher performance (because they are compiled into the server). Some modules are interpreters (eg, mod_php) and vary in the way they manage this instantiation/persistence/potential leak issue.


    No doubt that is a lot to absorb if you are just starting out with most of this stuff, lol -- sorry I can't make it simpler. You should actually post in more detail exactly what you are trying to accomplish. While using C with interpreted languages written in C (such as perl, php, and python) and apache (also a C native) is worth exploring, it's also nice to accomplish a task without taking half a year off to study So again, if you explain in more detail exactly what you want to do, someone might have a simpler solution.
    Last edited by MK27; 01-15-2012 at 07:54 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Jan 2012
    Posts
    14
    mk, I had to resort to sending you a PM because the system will not let me post message, despite there being no code in my reply. and anything remotely resembling code (I tried putting AND, NOT, OR, NAND, NOR in code tags) still gets kicked back. thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Scripting Languages that can be embedded in C++
    By TheSupremeAbode in forum C++ Programming
    Replies: 5
    Last Post: 06-20-2011, 03:20 AM
  2. Scripting Language
    By ~Kyo~ in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 12-12-2005, 09:10 AM
  3. What's the Difference Between a Programming Language and a Scripting Language?
    By Krak in forum A Brief History of Cprogramming.com
    Replies: 23
    Last Post: 07-15-2005, 04:46 PM
  4. Scripting language
    By Blizzarddog in forum C++ Programming
    Replies: 5
    Last Post: 09-17-2003, 11:47 AM
  5. Creating my own Scripting language in C++ for CGI
    By stovellpaul in forum C Programming
    Replies: 0
    Last Post: 10-01-2002, 03:41 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21