jjzjj

go - 用cgo编译出错

coder 2024-07-08 原文

因此,我试图在不忙等待的情况下从 stdin 读取,忽略 EOF,因为在我的案例中,客户端会来来去去。在 C 中,我会使用简单的 select() 或 poll(),但我正在尝试学习 Go,但我对缺少 select() 或 poll() 感到非常沮丧。我找不到在 Go 中使用 select 和 channels 的好方法,因为 Read() 将在 EOF 上立即返回,而我又回到了忙碌的等待状态。 syscall.Select() 似乎是最好的方法,但 Go 并没有费心去实现 FD_SET! 感叹

所以,我正在尝试使用 cgo。

package main

/*
#include <stdlib.h>
#include <sys/select.h>
void _FD_SET(int sysfd, void *set) {
    FD_SET(sysfd, (fd_set*)set);
}
*/
import "C"

import (
    "unsafe"

但是当我尝试在我的 Mac 上构建它时,我明白了。

# github.com/msoulier/mlogd
could not determine kind of name for C._FD_SET

clang errors for preamble:
src/github.com/msoulier/mlogd/mlogd.go:6:14: error: expected identifier or '('
void _FD_SET(int sysfd, void *set) {
             ^
src/github.com/msoulier/mlogd/mlogd.go:6:14: error: expected ')'
src/github.com/msoulier/mlogd/mlogd.go:6:13: note: to match this '('
void _FD_SET(int sysfd, void *set) {
            ^
2 errors generated.

如果我将导入合并在一起,那么大部分错误都会消失。

package main

/*
#include <stdlib.h>
#include <sys/select.h>
void _FD_SET(int sysfd, void *set) {
    FD_SET(sysfd, (fd_set*)set);
}
*/
import (
    "C"
    "unsafe"
    "syscall"

但是还有一个。

# github.com/msoulier/mlogd
could not determine kind of name for C._FD_SET

所以,我在这里寻找两件事。

  1. 为什么我在这里对 cgo 做错了?根据我的阅读,这应该“正常工作”。
  2. 有没有更好的方法可以无限期地从 stdin 读取数据,而无需忙于等待并忽略 EOF?

我的环境。

msoulier@merlin:~/work/go$ go version
go version go1.6.2 darwin/amd64
msoulier@merlin:~/work/go$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/msoulier/work/go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.6.2/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.6.2/libexec/pkg/tool/darwin_amd64"
GO15VENDOREXPERIMENT="1"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common"
CXX="clang++"
CGO_ENABLED="1"

提前致谢。必须比这更简单。

我通过 select 走到了这一步。

// loop forever - we expect to be killed with a SIGTERM or SIGINT
for {
    logger.Debug("going into select on stdin")
    var r_fdset syscall.FdSet
    for i := 0; i < 16; i++ {
        r_fdset.Bits[i] = 0
    }
    r_fdset.Bits[0] = 1
    selerr := syscall.Select(1, &r_fdset, nil, nil, nil)
    if selerr != nil {
        logger.Warning(selerr)
    }

但即使输入用完它也会立即返回。

迈克

最佳答案

在 Go 中,您执行阻塞操作。无处不在。

您将那些阻塞操作放在 goroutine 中,这些 goroutine 就像绿色线程/纤程一样。它们由 Go 运行时调度,可能在真实线程上,也可能共享线程。

然后您使用 channel 与您的 Go 程序的其他部分对话。

关于标准输入在 EOF 后始终可读的问题,请停止阅读。我的阅读器 goroutine 下面只是退出。

这里,有一个我刚刚写的例子:

package main

import (
    "fmt"
    "io"
    "os"
    "time"
)

func main() {
    var err error
    ch1 := make(chan []byte)
    ch2 := make(chan int)
    var buf []byte
    var i int
    var ok bool

    go reader(ch1)
    go counter(ch2)

    for {
        select {
        case buf, ok = <-ch1:
            if ok {
                _, err = os.Stdout.Write([]byte("input: "))
                _, err = os.Stdout.Write(buf)
            }

        case i, ok = <-ch2:
            if ok {
                _, err = fmt.Println("count", i)
            }
        }
        if err != nil {
            fmt.Println("error", err)
        }
        if !ok {
            break
        }
    }
}

func counter(ch chan<- int) {
    i := 0
    for i < 5 {
        i++
        ch <- i
        time.Sleep(time.Second)
    }
    close(ch)
}

func reader(ch chan<- []byte) {
    var r int
    var err error
    for {
        buf := make([]byte, 4000)
        r, err = os.Stdin.Read(buf)
        if r > 0 {
            ch <- buf[:r]
        }
        if err != nil {
            fmt.Println("read error", err)
            if err == io.EOF {
                break
            }
            // Or really just about any error on read is fatal
            break
        }
    }
    close(ch)
}

关于go - 用cgo编译出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38022991/

有关go - 用cgo编译出错的更多相关文章

  1. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

  2. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

  3. ruby - 安装libv8(3.11.8.13)出错,Bundler无法继续 - 2

    运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin

  4. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  5. .net - 是否有 Ruby .NET 编译器? - 2

    是否有适用于Ruby语言的.NETFramework编译器?我听说过DLR(动态语言运行时),这是否将使Ruby能够用于.NET开发? 最佳答案 IronRuby是Microsoft支持的项目,建立在动态语言运行时之上。 关于.net-是否有Ruby.NET编译器?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/199638/

  6. python - 使用 Python、Ruby 和 Perl 重新编译 MacPort 版本的 MacVim - 2

    关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭10年前。ImprovethisquestionLinux专家正在转向Mac(10.8)。因为我懒...我使用MacPorts安装MacVim。它似乎安装没有错误。我只需要mvim中的python、ruby和perl支持。$/opt/local/bin/mvim--version|egrep'patches|python|ruby|perl'Includedpatches:1-244,246-646+multi_lang-mzscheme+

  7. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  8. ruby - 为什么 `middleman serve` 有效,但是 `middleman build` 编译这个 Sass 失败? - 2

    当我刚刚运行middleman时服务,all.css编译得很好,只包含对+box-shadow(none)的调用:/*line1,/home/yang/asdf/source/stylesheets/content.css.sass*/div{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}但是当我构建网站时,我得到了这个Sass/Compass错误:$middlemanbuildSlim::EmbeddedEngineisdeprecated,itiscalledSlim::EmbeddedinSlim2.0

  9. ruby - 有没有办法在 Ruby 中执行编译时类型检查? - 2

    我知道Ruby是动态和强类型的,但据我所知,由于每个参数缺少显式类型表示法(或契约),当前语法不允许在编译时检查参数类型。如果我想执行编译时类型检查,我有哪些(实际成熟的)选项?更新我的意思是类型检查类似于典型的静态类型语言。比如C。例如,C函数表示每个参数的类型,编译器检查传入的参数是否正确。voidfunc1(structAAAaaa){structBBBbbb;func1(bbb);//Wrongtype.Compiletimeerror.}作为另一个例子,Objective-C通过放置显式类型信息来做到这一点。-(id)method1:(AAA*)aaa{BBB*bbb=[[A

  10. ruby - Ruby 将来可以编译并更快吗? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭7年前。ImprovethisquestionC、Java、C#和Python都是从头编译的。感谢Facebook,PHP现在也可以编译并可以在HHVM上运行,从而提高程序的性能。Ruby不可编译并且比上述语言慢。Ruby有没有可能在未来被编译(就像PHP和HHVM一样)?或者可能有一些原因不能做到?

随机推荐