FAQ
I'm trying to construct a Go interface to the Apache module system. I.e. I
want to be able to call Go functions from my Apache module. This is my Go
file:

     package main

     // #cgo CFLAGS: -I/usr/include/apache2 -I/usr/include/apr-1.0
     // #include <httpd.h>
     import "C"

     //export handler
     func handler(r *C.request_rec) int {
         ap_set_content_type(r, "text/html");
         ap_rprintf(r, "Hello, world from Go")
         return OK;
     }

When I build it (`go build mod_frugal.go`) I get this error:

     # command-line-arguments
     ./mod_frugal.go:8:17: type conversion loop at volatile *struct
apr_bucket

Line 8 is the line that function "handler" begins. Any suggestions?

Alternatively, when I build with cgo (`go tool cgo mod_frugal.go`) it
doesn't see my include directives at all:

     /home/vagrant/mod_frugal/src/mod_frugal.go:4:20: fatal error: httpd.h:
No such file or directory
     // #include <httpd.h>
                     ^
     compilation terminated.

I'm using "go version go1.2.1 linux/amd64".

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Safestylescripts at Jan 9, 2015 at 5:13 pm
    " I want to be able to call Go functions from my Apache module"

    Is that possible with CGO? I always though it was for Go to call C, not the
    other way round. Let me know if you do get this working! I'd love to link
    Go with Apache!

    On Friday, 9 January 2015 15:09:38 UTC, philne...@gmail.com wrote:

    I'm trying to construct a Go interface to the Apache module system. I.e. I
    want to be able to call Go functions from my Apache module. This is my Go
    file:

    package main

    // #cgo CFLAGS: -I/usr/include/apache2 -I/usr/include/apr-1.0
    // #include <httpd.h>
    import "C"

    //export handler
    func handler(r *C.request_rec) int {
    ap_set_content_type(r, "text/html");
    ap_rprintf(r, "Hello, world from Go")
    return OK;
    }

    When I build it (`go build mod_frugal.go`) I get this error:

    # command-line-arguments
    ./mod_frugal.go:8:17: type conversion loop at volatile *struct
    apr_bucket

    Line 8 is the line that function "handler" begins. Any suggestions?

    Alternatively, when I build with cgo (`go tool cgo mod_frugal.go`) it
    doesn't see my include directives at all:

    /home/vagrant/mod_frugal/src/mod_frugal.go:4:20: fatal error: httpd.h:
    No such file or directory
    // #include <httpd.h>
    ^
    compilation terminated.

    I'm using "go version go1.2.1 linux/amd64".
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Philneaton95 at Jan 9, 2015 at 5:39 pm
    One other thing to note... when I prefix the two Apache calls with "C.":

    package main

    // #cgo CFLAGS: -I/usr/include/apache2 -I/usr/include/apr-1.0
    // #include "mod_frugal.h"
    import "C"

    //export handler
    func handler(r *C.struct_request_rec) int {
         C.ap_set_content_type(r, "text/html")
         C.ap_rprintf(r, "<h1>Hello, world from Go!</h1>")
         return OK
    }

    the original error goes away and I get this one:

    # _/home/vagrant/mod_frugal/src
    37: error: 'ap_set_content_type' undeclared (first use in this function)
    37: error: 'ap_rprintf' undeclared (first use in this function)
    On Friday, January 9, 2015 at 10:09:38 AM UTC-5, philne...@gmail.com wrote:

    I'm trying to construct a Go interface to the Apache module system. I.e. I
    want to be able to call Go functions from my Apache module. This is my Go
    file:

    package main

    // #cgo CFLAGS: -I/usr/include/apache2 -I/usr/include/apr-1.0
    // #include <httpd.h>
    import "C"

    //export handler
    func handler(r *C.request_rec) int {
    ap_set_content_type(r, "text/html");
    ap_rprintf(r, "Hello, world from Go")
    return OK;
    }

    When I build it (`go build mod_frugal.go`) I get this error:

    # command-line-arguments
    ./mod_frugal.go:8:17: type conversion loop at volatile *struct
    apr_bucket

    Line 8 is the line that function "handler" begins. Any suggestions?

    Alternatively, when I build with cgo (`go tool cgo mod_frugal.go`) it
    doesn't see my include directives at all:

    /home/vagrant/mod_frugal/src/mod_frugal.go:4:20: fatal error: httpd.h:
    No such file or directory
    // #include <httpd.h>
    ^
    compilation terminated.

    I'm using "go version go1.2.1 linux/amd64".
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Philneaton95 at Jan 9, 2015 at 7:50 pm
    Updated my Go file like this:

    package main

    // #cgo CFLAGS: -I/usr/include/apache2 -I/usr/include/apr-1.0
    -Wl,--unresolved-symbols=ignore-all -Wl,--warn-unresolved-symbols
    // #include "mod_frugal.h"
    import "C"

    import "unsafe"

    //export handler
    func handler(r unsafe.Pointer) int {
         C.go_ap_set_content_type(r, "text/html")
         C.go_ap_rprintf(r, "<h1>Hello, world from Go!</h1>")
         return OK
    }

    And created a header file to wrap the Apache calls:

    #ifndef MOD_FRUGAL_H
    #define MOD_FRUGAL_H

    #include <httpd.h>
    #include <http_protocol.h>

    typedef void* Request;

    static void go_ap_set_content_type(Request r, const char* t) {
         ap_set_content_type((request_rec*)r, t);
    }

    static void go_ap_rprintf(Request r, const char* t) {
         ap_rprintf((request_rec*)r, t);
    }

    #endif

    So now I get this linker error:

    # _/home/vagrant/mod_frugal/src/go_src
    /tmp/go-build271197778/_/home/vagrant/mod_frugal/src/go_src/_obj/mod_frugal.cgo2.o:
    In function `go_ap_rprintf':
    ./mod_frugal.h:14: undefined reference to `ap_rprintf'
    /tmp/go-build271197778/_/home/vagrant/mod_frugal/src/go_src/_obj/mod_frugal.cgo2.o:
    In function `go_ap_set_content_type':
    ./mod_frugal.h:10: undefined reference to `ap_set_content_type'
    collect2: error: ld returned 1 exit status

    Seems like I'm pretty close. I'm just not sure what to link this against.
    On Friday, January 9, 2015 at 10:09:38 AM UTC-5, philne...@gmail.com wrote:

    I'm trying to construct a Go interface to the Apache module system. I.e. I
    want to be able to call Go functions from my Apache module. This is my Go
    file:

    package main

    // #cgo CFLAGS: -I/usr/include/apache2 -I/usr/include/apr-1.0
    // #include <httpd.h>
    import "C"

    //export handler
    func handler(r *C.request_rec) int {
    ap_set_content_type(r, "text/html");
    ap_rprintf(r, "Hello, world from Go")
    return OK;
    }

    When I build it (`go build mod_frugal.go`) I get this error:

    # command-line-arguments
    ./mod_frugal.go:8:17: type conversion loop at volatile *struct
    apr_bucket

    Line 8 is the line that function "handler" begins. Any suggestions?

    Alternatively, when I build with cgo (`go tool cgo mod_frugal.go`) it
    doesn't see my include directives at all:

    /home/vagrant/mod_frugal/src/mod_frugal.go:4:20: fatal error: httpd.h:
    No such file or directory
    // #include <httpd.h>
    ^
    compilation terminated.

    I'm using "go version go1.2.1 linux/amd64".
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • James Bardin at Jan 9, 2015 at 8:08 pm

    On Friday, January 9, 2015 at 2:49:58 PM UTC-5, philne...@gmail.com wrote:

    Seems like I'm pretty close. I'm just not sure what to link this against.
    You are not going to be able to call go from an apache module. The go
    program has to be the main process to setup the runtime. Go currently
    doesn't support creating shared libraries.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Philneaton95 at Jan 9, 2015 at 8:22 pm
    Let me show you my mod_frugal.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "ap_provider.h"
    #include "httpd.h"
    #include "http_core.h"
    #include "http_protocol.h"
    #include "http_request.h"

    extern int handler(void*);

    static int frugal_handler(request_rec* r) {
         int status = handler(r);
         return status;
    }

    static void register_hooks(apr_pool_t *pool) {
         ap_hook_handler(frugal_handler, NULL, NULL, APR_HOOK_LAST);
    }

    module AP_MODULE_DECLARE_DATA futile_module = {
         STANDARD20_MODULE_STUFF,
         NULL,
         NULL,
         NULL,
         NULL,
         NULL,
         register_hooks
    };

    This is the what apxs sees. I am just trying to hook into Go... or out of
    it. I'm having trouble explaining exactly what I'm trying to do but this C
    file should make it clear. I do believe this is possible if I can get the
    other aspects of compiling the Go into something accessible by C. Correct
    me if I'm still understanding. I definitely am new to Go.
    On Friday, January 9, 2015 at 3:08:45 PM UTC-5, James Bardin wrote:


    On Friday, January 9, 2015 at 2:49:58 PM UTC-5, philne...@gmail.com wrote:


    Seems like I'm pretty close. I'm just not sure what to link this against.
    You are not going to be able to call go from an apache module. The go
    program has to be the main process to setup the runtime. Go currently
    doesn't support creating shared libraries.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Philneaton95 at Jan 9, 2015 at 8:25 pm
    Again, correct me if I'm wrong, but this Stack post
    <http://stackoverflow.com/a/15760986/1507139> seems to be doing exactly
    what I'm trying to do except without dependencies.
    On Friday, January 9, 2015 at 3:22:34 PM UTC-5, philne...@gmail.com wrote:

    Let me show you my mod_frugal.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "ap_provider.h"
    #include "httpd.h"
    #include "http_core.h"
    #include "http_protocol.h"
    #include "http_request.h"

    extern int handler(void*);

    static int frugal_handler(request_rec* r) {
    int status = handler(r);
    return status;
    }

    static void register_hooks(apr_pool_t *pool) {
    ap_hook_handler(frugal_handler, NULL, NULL, APR_HOOK_LAST);
    }

    module AP_MODULE_DECLARE_DATA futile_module = {
    STANDARD20_MODULE_STUFF,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    register_hooks
    };

    This is the what apxs sees. I am just trying to hook into Go... or out of
    it. I'm having trouble explaining exactly what I'm trying to do but this C
    file should make it clear. I do believe this is possible if I can get the
    other aspects of compiling the Go into something accessible by C. Correct
    me if I'm still understanding. I definitely am new to Go.
    On Friday, January 9, 2015 at 3:08:45 PM UTC-5, James Bardin wrote:



    On Friday, January 9, 2015 at 2:49:58 PM UTC-5, philne...@gmail.com
    wrote:

    Seems like I'm pretty close. I'm just not sure what to link this against.
    You are not going to be able to call go from an apache module. The go
    program has to be the main process to setup the runtime. Go currently
    doesn't support creating shared libraries.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • James Bardin at Jan 10, 2015 at 3:09 am

    On Fri, Jan 9, 2015 at 3:25 PM, <philneaton95@gmail.com wrote:

    Again, correct me if I'm wrong, but this Stack post
    <http://stackoverflow.com/a/15760986/1507139> seems to be doing exactly
    what I'm trying to do except without dependencies.
    That's a hack using gccgo, and I have no idea what you can actually make
    available to the calling program. There's only a small note about it in the
    faq:
    Gccgo is a GCC front-end that can, with care, be linked with GCC-compiled
    C or C++ programs.

    I do believe this is possible if I can get the other aspects of compiling
    the Go into something accessible by C. Correct me if I'm still
    understanding. I definitely am new to Go.
    That is precisely what you can't do with the go toolchain. There's a
    proposal for other execution modes for Go, e.g. from a shared library, but
    that's not going to happen for a while. Until then, the Go runtime has to
    be the process entry point.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Minux at Jan 10, 2015 at 4:30 am

    On Fri, Jan 9, 2015 at 3:08 PM, James Bardin wrote:
    On Friday, January 9, 2015 at 2:49:58 PM UTC-5, philne...@gmail.com wrote:

    Seems like I'm pretty close. I'm just not sure what to link this against.
    You are not going to be able to call go from an apache module. The go
    program has to be the main process to setup the runtime.
    Not impossible. Just hard.

    It's possible to compile the Go code as a (static) object file, and link
    with the
    other part of program. You need to start the Go runtime before calling back
    tp
    cgo exported functions, but Go doesn't need to control the real main.

    Hint: essentially the external linking support for Go compiles Go code into
    a
    static object file. What if you rename the entry point in
    rt0_$GOOS_$GOARCH.s
    to something other than "main", and call it to start the Go runtime? (This
    is how
    the Android port works, except that it generates a position-dependent shared
    library.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Philneaton95 at Jan 10, 2015 at 2:34 pm
    My most recent attempt came up right with what James was talking about.
    Here is mod_frugal.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "ap_provider.h"
    #include "httpd.h"
    #include "http_core.h"
    #include "http_protocol.h"
    #include "http_request.h"

    extern int handler(void*) __asm__ ("frugal2.main.handler");

    static int frugal_handler(request_rec* r) {
         int status = handler(r);
         return status;
    }

    static void register_hooks(apr_pool_t *pool) {
         ap_hook_handler(frugal_handler, NULL, NULL, APR_HOOK_LAST);
    }

    module AP_MODULE_DECLARE_DATA frugal2_module = {
         STANDARD20_MODULE_STUFF,
         NULL,
         NULL,
         NULL,
         NULL,
         NULL,
         register_hooks
    };


    Here is frugal2.go:


    package main

    import "unsafe"

    //extern ap_set_content_type
    func c_ap_set_content_type(r unsafe.Pointer, t []byte)

    //extern ap_rprintf
    func c_ap_rprintf(r unsafe.Pointer, t []byte)

    func handler(r unsafe.Pointer) int {
         c_ap_set_content_type(r, []byte("text/html"))
         c_ap_rprintf(r, []byte("<h1>Hello, world from Go!</h1>"))
         return 0
    }


    This is my compilation script:


    libtool --tag=CC --mode=compile gccgo -c frugal2.go -o frugal2.o -fgo-prefix=frugal2 -static-libgo
    apxs -c frugal2.lo mod_frugal2.c
    sudo apxs -ai -n frugal2 mod_frugal2.la


    And I get no error until I restart apache at which point this comes up:


    Output of config test was:
    apache2: Syntax error on line 140 of /etc/apache2/apache2.conf: Syntax error on line 1 of /etc/apache2/mods-enabled/frugal2.load: Cannot load /usr/lib/apache2/modules/mod_frugal2.so into server: /usr/lib/apache2/modules/mod_frugal2.so: undefined symbol: __go_new
    Action 'configtest' failed.


    So it looks like James was right, until you sent this message. I'll give this a shot! Thanks for the suggestion!

    On Friday, January 9, 2015 at 11:31:21 PM UTC-5, minux wrote:


    On Fri, Jan 9, 2015 at 3:08 PM, James Bardin <j.ba...@gmail.com
    <javascript:>> wrote:
    On Friday, January 9, 2015 at 2:49:58 PM UTC-5, philne...@gmail.com
    wrote:
    Seems like I'm pretty close. I'm just not sure what to link this against.
    You are not going to be able to call go from an apache module. The go
    program has to be the main process to setup the runtime.
    Not impossible. Just hard.

    It's possible to compile the Go code as a (static) object file, and link
    with the
    other part of program. You need to start the Go runtime before calling
    back tp
    cgo exported functions, but Go doesn't need to control the real main.

    Hint: essentially the external linking support for Go compiles Go code
    into a
    static object file. What if you rename the entry point in
    rt0_$GOOS_$GOARCH.s
    to something other than "main", and call it to start the Go runtime? (This
    is how
    the Android port works, except that it generates a position-dependent
    shared
    library.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJan 9, '15 at 3:55p
activeJan 10, '15 at 2:34p
posts10
users4
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase