Can't open file when calling golang function via Node












1















I followed the tutorial in https://medium.com/learning-the-go-programming-language/calling-go-functions-from-other-languages-4c7d8bcc69bf to make my node app able to call golang function. The provided example works like a charm.

I do, however, unable it to implement in another scenario. Here I want to open a file by providing only it's absolute path and call the Go's function, but it always told me that it can't find the file due to no such file. I'm trying to run it directly in Go and it works!

Am I doing it wrong or is it an actual bug/unfinished feature?



Here is the golang source that I've built to c-style lib :



package main

import "C"

import (
"bufio"
"fmt"
"log"
"os"
)

func main() {}

//export ReadSomething
func ReadSomething(filePath string) {
file, err := os.Open(filePath)
if err != nil {
log.Fatal(err)
}

defer file.Close()

scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}

if err := scanner.Err(); err != nil {
log.Fatal(err)
}

}


I built it with this command :



go build -buildmode=c-shared -o simpleread.so main.go


In case you're wondering what's the header output :



/* Created by "go tool cgo" - DO NOT EDIT. */

/* package command-line-arguments */

#line 1 "cgo-builtin-prolog"

#include <stddef.h> /* for ptrdiff_t below */

#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H

typedef struct { const char *p; ptrdiff_t n; } _GoString_;

#endif

/* Start of preamble from import "C" comments. */
/* End of preamble from import "C" comments. */


/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"

#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H

typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;

/*
static assertion to make sure the file is being used on architecture
at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];

typedef _GoString_ GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

#endif

/* End of boilerplate cgo prologue. */

#ifdef __cplusplus
extern "C" {
#endif


extern void ReadSomething(GoString p0);

#ifdef __cplusplus
}
#endif


And then, below is how I call it via Node. I give the comment on the line where the error generated :



var ref = require("ref")
var ffi = require("ffi-napi")
var Struct = require("ref-struct")
var ArrayType = require("ref-array")
var LongArray = ArrayType(ref.types.longlong);

var GoString = Struct({
p: "string",
n: "longlong"
});

var simpleRead = ffi.Library("./simpleread.so", {
ReadSomething: ["void", [GoString]]
});

// error here, can't open the specified file
simpleRead.ReadSomething("/home/ivan/Documents/crashsite/node-go-crossfire/simpletext.txt")


I'm running it on Ubuntu 18.04 64bit.










share|improve this question





























    1















    I followed the tutorial in https://medium.com/learning-the-go-programming-language/calling-go-functions-from-other-languages-4c7d8bcc69bf to make my node app able to call golang function. The provided example works like a charm.

    I do, however, unable it to implement in another scenario. Here I want to open a file by providing only it's absolute path and call the Go's function, but it always told me that it can't find the file due to no such file. I'm trying to run it directly in Go and it works!

    Am I doing it wrong or is it an actual bug/unfinished feature?



    Here is the golang source that I've built to c-style lib :



    package main

    import "C"

    import (
    "bufio"
    "fmt"
    "log"
    "os"
    )

    func main() {}

    //export ReadSomething
    func ReadSomething(filePath string) {
    file, err := os.Open(filePath)
    if err != nil {
    log.Fatal(err)
    }

    defer file.Close()

    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
    fmt.Println(scanner.Text())
    }

    if err := scanner.Err(); err != nil {
    log.Fatal(err)
    }

    }


    I built it with this command :



    go build -buildmode=c-shared -o simpleread.so main.go


    In case you're wondering what's the header output :



    /* Created by "go tool cgo" - DO NOT EDIT. */

    /* package command-line-arguments */

    #line 1 "cgo-builtin-prolog"

    #include <stddef.h> /* for ptrdiff_t below */

    #ifndef GO_CGO_EXPORT_PROLOGUE_H
    #define GO_CGO_EXPORT_PROLOGUE_H

    typedef struct { const char *p; ptrdiff_t n; } _GoString_;

    #endif

    /* Start of preamble from import "C" comments. */
    /* End of preamble from import "C" comments. */


    /* Start of boilerplate cgo prologue. */
    #line 1 "cgo-gcc-export-header-prolog"

    #ifndef GO_CGO_PROLOGUE_H
    #define GO_CGO_PROLOGUE_H

    typedef signed char GoInt8;
    typedef unsigned char GoUint8;
    typedef short GoInt16;
    typedef unsigned short GoUint16;
    typedef int GoInt32;
    typedef unsigned int GoUint32;
    typedef long long GoInt64;
    typedef unsigned long long GoUint64;
    typedef GoInt64 GoInt;
    typedef GoUint64 GoUint;
    typedef __SIZE_TYPE__ GoUintptr;
    typedef float GoFloat32;
    typedef double GoFloat64;
    typedef float _Complex GoComplex64;
    typedef double _Complex GoComplex128;

    /*
    static assertion to make sure the file is being used on architecture
    at least with matching size of GoInt.
    */
    typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];

    typedef _GoString_ GoString;
    typedef void *GoMap;
    typedef void *GoChan;
    typedef struct { void *t; void *v; } GoInterface;
    typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

    #endif

    /* End of boilerplate cgo prologue. */

    #ifdef __cplusplus
    extern "C" {
    #endif


    extern void ReadSomething(GoString p0);

    #ifdef __cplusplus
    }
    #endif


    And then, below is how I call it via Node. I give the comment on the line where the error generated :



    var ref = require("ref")
    var ffi = require("ffi-napi")
    var Struct = require("ref-struct")
    var ArrayType = require("ref-array")
    var LongArray = ArrayType(ref.types.longlong);

    var GoString = Struct({
    p: "string",
    n: "longlong"
    });

    var simpleRead = ffi.Library("./simpleread.so", {
    ReadSomething: ["void", [GoString]]
    });

    // error here, can't open the specified file
    simpleRead.ReadSomething("/home/ivan/Documents/crashsite/node-go-crossfire/simpletext.txt")


    I'm running it on Ubuntu 18.04 64bit.










    share|improve this question



























      1












      1








      1








      I followed the tutorial in https://medium.com/learning-the-go-programming-language/calling-go-functions-from-other-languages-4c7d8bcc69bf to make my node app able to call golang function. The provided example works like a charm.

      I do, however, unable it to implement in another scenario. Here I want to open a file by providing only it's absolute path and call the Go's function, but it always told me that it can't find the file due to no such file. I'm trying to run it directly in Go and it works!

      Am I doing it wrong or is it an actual bug/unfinished feature?



      Here is the golang source that I've built to c-style lib :



      package main

      import "C"

      import (
      "bufio"
      "fmt"
      "log"
      "os"
      )

      func main() {}

      //export ReadSomething
      func ReadSomething(filePath string) {
      file, err := os.Open(filePath)
      if err != nil {
      log.Fatal(err)
      }

      defer file.Close()

      scanner := bufio.NewScanner(file)
      for scanner.Scan() {
      fmt.Println(scanner.Text())
      }

      if err := scanner.Err(); err != nil {
      log.Fatal(err)
      }

      }


      I built it with this command :



      go build -buildmode=c-shared -o simpleread.so main.go


      In case you're wondering what's the header output :



      /* Created by "go tool cgo" - DO NOT EDIT. */

      /* package command-line-arguments */

      #line 1 "cgo-builtin-prolog"

      #include <stddef.h> /* for ptrdiff_t below */

      #ifndef GO_CGO_EXPORT_PROLOGUE_H
      #define GO_CGO_EXPORT_PROLOGUE_H

      typedef struct { const char *p; ptrdiff_t n; } _GoString_;

      #endif

      /* Start of preamble from import "C" comments. */
      /* End of preamble from import "C" comments. */


      /* Start of boilerplate cgo prologue. */
      #line 1 "cgo-gcc-export-header-prolog"

      #ifndef GO_CGO_PROLOGUE_H
      #define GO_CGO_PROLOGUE_H

      typedef signed char GoInt8;
      typedef unsigned char GoUint8;
      typedef short GoInt16;
      typedef unsigned short GoUint16;
      typedef int GoInt32;
      typedef unsigned int GoUint32;
      typedef long long GoInt64;
      typedef unsigned long long GoUint64;
      typedef GoInt64 GoInt;
      typedef GoUint64 GoUint;
      typedef __SIZE_TYPE__ GoUintptr;
      typedef float GoFloat32;
      typedef double GoFloat64;
      typedef float _Complex GoComplex64;
      typedef double _Complex GoComplex128;

      /*
      static assertion to make sure the file is being used on architecture
      at least with matching size of GoInt.
      */
      typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];

      typedef _GoString_ GoString;
      typedef void *GoMap;
      typedef void *GoChan;
      typedef struct { void *t; void *v; } GoInterface;
      typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

      #endif

      /* End of boilerplate cgo prologue. */

      #ifdef __cplusplus
      extern "C" {
      #endif


      extern void ReadSomething(GoString p0);

      #ifdef __cplusplus
      }
      #endif


      And then, below is how I call it via Node. I give the comment on the line where the error generated :



      var ref = require("ref")
      var ffi = require("ffi-napi")
      var Struct = require("ref-struct")
      var ArrayType = require("ref-array")
      var LongArray = ArrayType(ref.types.longlong);

      var GoString = Struct({
      p: "string",
      n: "longlong"
      });

      var simpleRead = ffi.Library("./simpleread.so", {
      ReadSomething: ["void", [GoString]]
      });

      // error here, can't open the specified file
      simpleRead.ReadSomething("/home/ivan/Documents/crashsite/node-go-crossfire/simpletext.txt")


      I'm running it on Ubuntu 18.04 64bit.










      share|improve this question
















      I followed the tutorial in https://medium.com/learning-the-go-programming-language/calling-go-functions-from-other-languages-4c7d8bcc69bf to make my node app able to call golang function. The provided example works like a charm.

      I do, however, unable it to implement in another scenario. Here I want to open a file by providing only it's absolute path and call the Go's function, but it always told me that it can't find the file due to no such file. I'm trying to run it directly in Go and it works!

      Am I doing it wrong or is it an actual bug/unfinished feature?



      Here is the golang source that I've built to c-style lib :



      package main

      import "C"

      import (
      "bufio"
      "fmt"
      "log"
      "os"
      )

      func main() {}

      //export ReadSomething
      func ReadSomething(filePath string) {
      file, err := os.Open(filePath)
      if err != nil {
      log.Fatal(err)
      }

      defer file.Close()

      scanner := bufio.NewScanner(file)
      for scanner.Scan() {
      fmt.Println(scanner.Text())
      }

      if err := scanner.Err(); err != nil {
      log.Fatal(err)
      }

      }


      I built it with this command :



      go build -buildmode=c-shared -o simpleread.so main.go


      In case you're wondering what's the header output :



      /* Created by "go tool cgo" - DO NOT EDIT. */

      /* package command-line-arguments */

      #line 1 "cgo-builtin-prolog"

      #include <stddef.h> /* for ptrdiff_t below */

      #ifndef GO_CGO_EXPORT_PROLOGUE_H
      #define GO_CGO_EXPORT_PROLOGUE_H

      typedef struct { const char *p; ptrdiff_t n; } _GoString_;

      #endif

      /* Start of preamble from import "C" comments. */
      /* End of preamble from import "C" comments. */


      /* Start of boilerplate cgo prologue. */
      #line 1 "cgo-gcc-export-header-prolog"

      #ifndef GO_CGO_PROLOGUE_H
      #define GO_CGO_PROLOGUE_H

      typedef signed char GoInt8;
      typedef unsigned char GoUint8;
      typedef short GoInt16;
      typedef unsigned short GoUint16;
      typedef int GoInt32;
      typedef unsigned int GoUint32;
      typedef long long GoInt64;
      typedef unsigned long long GoUint64;
      typedef GoInt64 GoInt;
      typedef GoUint64 GoUint;
      typedef __SIZE_TYPE__ GoUintptr;
      typedef float GoFloat32;
      typedef double GoFloat64;
      typedef float _Complex GoComplex64;
      typedef double _Complex GoComplex128;

      /*
      static assertion to make sure the file is being used on architecture
      at least with matching size of GoInt.
      */
      typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];

      typedef _GoString_ GoString;
      typedef void *GoMap;
      typedef void *GoChan;
      typedef struct { void *t; void *v; } GoInterface;
      typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

      #endif

      /* End of boilerplate cgo prologue. */

      #ifdef __cplusplus
      extern "C" {
      #endif


      extern void ReadSomething(GoString p0);

      #ifdef __cplusplus
      }
      #endif


      And then, below is how I call it via Node. I give the comment on the line where the error generated :



      var ref = require("ref")
      var ffi = require("ffi-napi")
      var Struct = require("ref-struct")
      var ArrayType = require("ref-array")
      var LongArray = ArrayType(ref.types.longlong);

      var GoString = Struct({
      p: "string",
      n: "longlong"
      });

      var simpleRead = ffi.Library("./simpleread.so", {
      ReadSomething: ["void", [GoString]]
      });

      // error here, can't open the specified file
      simpleRead.ReadSomething("/home/ivan/Documents/crashsite/node-go-crossfire/simpletext.txt")


      I'm running it on Ubuntu 18.04 64bit.







      node.js go






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 20 '18 at 15:20







      imeluntuk

















      asked Nov 20 '18 at 15:14









      imeluntukimeluntuk

      84113




      84113
























          1 Answer
          1






          active

          oldest

          votes


















          1














          Remember that strings in Go are like slices. They are composed of a pointer to the backing data and the length. This is why in your code, GoString is defined as:



          var GoString = Struct({
          p: "string", // pointer
          n: "longlong" // length
          });


          I'd recommend you define a function for creating a GoString e.g.



          function NewGoString(str) {
          return new GoString({p: str, n: str.length})
          }


          Which you can use in your code like:



          var simpleRead = ffi.Library("./simpleread.so", {
          ReadSomething: ["void", [GoString]]
          });

          simpleRead.ReadSomething(NewGoString("/path/to/your/file"))





          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396055%2fcant-open-file-when-calling-golang-function-via-node%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            Remember that strings in Go are like slices. They are composed of a pointer to the backing data and the length. This is why in your code, GoString is defined as:



            var GoString = Struct({
            p: "string", // pointer
            n: "longlong" // length
            });


            I'd recommend you define a function for creating a GoString e.g.



            function NewGoString(str) {
            return new GoString({p: str, n: str.length})
            }


            Which you can use in your code like:



            var simpleRead = ffi.Library("./simpleread.so", {
            ReadSomething: ["void", [GoString]]
            });

            simpleRead.ReadSomething(NewGoString("/path/to/your/file"))





            share|improve this answer




























              1














              Remember that strings in Go are like slices. They are composed of a pointer to the backing data and the length. This is why in your code, GoString is defined as:



              var GoString = Struct({
              p: "string", // pointer
              n: "longlong" // length
              });


              I'd recommend you define a function for creating a GoString e.g.



              function NewGoString(str) {
              return new GoString({p: str, n: str.length})
              }


              Which you can use in your code like:



              var simpleRead = ffi.Library("./simpleread.so", {
              ReadSomething: ["void", [GoString]]
              });

              simpleRead.ReadSomething(NewGoString("/path/to/your/file"))





              share|improve this answer


























                1












                1








                1







                Remember that strings in Go are like slices. They are composed of a pointer to the backing data and the length. This is why in your code, GoString is defined as:



                var GoString = Struct({
                p: "string", // pointer
                n: "longlong" // length
                });


                I'd recommend you define a function for creating a GoString e.g.



                function NewGoString(str) {
                return new GoString({p: str, n: str.length})
                }


                Which you can use in your code like:



                var simpleRead = ffi.Library("./simpleread.so", {
                ReadSomething: ["void", [GoString]]
                });

                simpleRead.ReadSomething(NewGoString("/path/to/your/file"))





                share|improve this answer













                Remember that strings in Go are like slices. They are composed of a pointer to the backing data and the length. This is why in your code, GoString is defined as:



                var GoString = Struct({
                p: "string", // pointer
                n: "longlong" // length
                });


                I'd recommend you define a function for creating a GoString e.g.



                function NewGoString(str) {
                return new GoString({p: str, n: str.length})
                }


                Which you can use in your code like:



                var simpleRead = ffi.Library("./simpleread.so", {
                ReadSomething: ["void", [GoString]]
                });

                simpleRead.ReadSomething(NewGoString("/path/to/your/file"))






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 20 '18 at 18:22









                ssemillassemilla

                3,097524




                3,097524
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53396055%2fcant-open-file-when-calling-golang-function-via-node%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Guess what letter conforming each word

                    Port of Spain

                    Run scheduled task as local user group (not BUILTIN)