在现有 C 项目中使用 Go 代码

2023-12-21

自从 Go 1.5 发布以来,我开始重新考虑如何将它集成到我现有的项目中。

该项目的代码库完全用 C 编写,用于对硬件和其他有趣的东西进行低级访问。然而,一些更高层次的东西很乏味,我想开始用更高层次的语言(Go)来编写它们

有什么方法可以从 C 程序调用 Go 代码吗?我安装了Go 1.5,其中添加了-buildmode=c-archive (https://golang.org/s/execmodes https://golang.org/s/execmodes)我正在努力让它工作。

但是,我似乎无法让 Go 生成适当的头文件来允许我的项目实际编译。当我生成存档时,我在导出的符号中看到该函数(使用 objdump),但没有包含 gcc 的头文件抱怨该函数不存在(如预期)

我对 Go 还很陌生——但是,我喜欢这门语言并且想使用它。是否有任何惯用的方式(我认为“惯用”在 Go 世界中被广泛使用......)可以让它们彼此很好地配合?

我问这个问题并特别提到 Go 1.5 的原因是根据这篇文档,https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit?pli=1#heading=h.1gw5ytjfcoke https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit?pli=1#heading=h.1gw5ytjfcokeGo 1.5 添加了对非 Go 程序调用 Go 代码的支持。具体来说,在“链接到非 Go 程序并从中调用的 Go 代码”部分中提到


要构建可从 C 调用的存档,您需要将它们标记为导出的 CGo 符号。
例如,如果我创建一个文件foo.go包含以下内容:

package main

import (
    "C"
    "fmt"
)

//export PrintInt
func PrintInt(x int) {
    fmt.Println(x)
}

func main() {}

需要注意的重要事项是:

  • 需要调用该包main
  • 你需要有一个main函数,尽管它可以为空。
  • 您需要导入包C
  • 你需要特别的//export注释来标记您希望从 C 调用的函数。

我可以使用以下命令将其编译为 C 可调用静态库:

go build -buildmode=c-archive foo.go

结果将存档foo.a和一个标题foo.h。在标题中,我们得到以下内容(删除不相关的部分):

...
typedef long long GoInt64;
...
typedef GoInt64 GoInt;
...
extern void PrintInt(GoInt p0);
...

这样就足以调用导出的函数了。我们可以编写一个简单的 C 程序来调用它,如下所示:

#include "foo.h"

int main(int argc, char **argv) {
    PrintInt(42);
    return 0;
}

我们可以使用如下命令来编译它:

gcc -pthread foo.c foo.a -o foo

The -pthread需要选项是因为 Go 运行时使用线程。当我运行生成的可执行文件时,它会打印42.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在现有 C 项目中使用 Go 代码 的相关文章

随机推荐

  • nginx 配置以启用具有源匹配的 CORS

    我尝试过使用一个非常流行的配置 https gist github com Stanback 7145487对于nginx 它启用了CORS并支持使用正则表达式进行源匹配 这是我的配置 server listen 80 default se
  • 如何在 C# 中更改 WebBrowser 控件用户代理 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我是在 C 中使用 WebBrows
  • 使用 FFT 结果重新创建时间序列数据,而不使用 ifft

    我使用 fft 分析了 sunspots dat 数据 如下 这是该领域的一个经典示例 我从实部和虚部的 FFT 中获得了结果 然后我尝试使用这些系数 前 20 个 按照傅立叶变换公式重新创建数据 认为实部对应于a n 想象部分对应于b n
  • 如何在 K - 均值算法中优化 K [重复]

    这个问题在这里已经有答案了 可能的重复 使用 k 均值聚类时如何确定 k https stackoverflow com questions 1793532 how do i determine k when using k means c
  • Python 中的 CSV 列到数组

    我很难处理一个在我看来很简单的问题 我正在尝试导入 csv 并将其列拆分为数组 我可以对其运行不同的操作 然后 zip 重新组合在一起 import csv data csv reader open test csv rb delimite
  • 通过 VSTS 在 azure 部署中包含节点模块

    我有一个 Azure 应用程序服务 需要将其部署为 VSTS 中发布定义的一部分 为了提供一些上下文 它是一个 ASP NET MVC 应用程序并使用 Angular 2 它还有一个 package json 文件 我有一个 VSTS 构建
  • 使用 Raw-Loader 将 SVG 标记嵌入 vue-component 中

    我正在使用 webpack 导入 SVG原始装载机 https github com webpack contrib raw loader 这意味着我想将实际的 SVG XML 按原样嵌入到我的标记中 我正在尝试执行以下操作
  • 将 2D 数组索引转换为 1D 索引

    我有两个用于国际象棋变体的数组 我正在用java编码 到目前为止 我有一个控制台版本 它将棋盘表示为一维数组 大小为32 但我正在为其制作一个GUI 我想要它显示为 4x8 网格 所以我有一个 JPanel 的二维数组 问题是 考虑到它是一
  • Android VideoView 错误 1,0

    我有一个应用程序 其主要目标是播放特定的视频文件 有时它可以正确播放视频 但其他时候它会给我这个错误 03 21 14 52 36 181 I AwesomePlayer 119 setDataSource l data data my p
  • 在普通 for 循环中更改 QVector 的对象

    如果我有一个 QVector 我可以使用基于范围的循环 使用引用并更改 QVector 中的对象 但如果我在修改对象时需要索引 我必须使用普通的 for 循环 但是我怎样才能改变 QVector 中对象的值呢 作为解决方法 我在更改临时对象
  • 计算与“hetcor”的多向相关性时,有关 log(P) 的警告消息的含义是什么?

    计算 R 中的多向相关性时 library polycor 功能hetcor 我收到警告消息In log P NaNs produced 我无法弄清楚这个警告消息可能构成什么 我认为这与测试二元正态性的 p 值的计算有关 因此我的问题是 该
  • 在twisted中使用pymongo究竟有什么问题?

    我有一个扭曲的服务器应用程序 它与大约 1000 个客户端保持持久连接 每个客户端偶尔都会向我的扭曲服务器发送数据 我希望该服务器将数据存储到 MongoDB 数据库中 到目前为止 一切都很好 但是 pymongo 文档指出 没有好的方法可
  • React Native滚动视图禁用拉动刷新

    我正在使用 React Native v0 44 2 的滚动视图 我想禁用拉动刷新并仅生成我的视图的滚动 是否有另一种方法可以在不使用滚动视图的情况下做到这一点 我看到了一些旧版本 我不知道我是否最近放了这个动画 所以我的代码如下 rend
  • 如何在 Solr 3.6 中对两个字段进行排序

    在网络请求 URL 中有一个 排序 选项 但是 如何按两个字段排序 如果我做类似的事情 sort field1 asc sort field2 desc 根据我的观察 只有第一个字段将用于排序 你这样做 sort field1 asc fi
  • 由于单声道模块依赖性,XSP 配置失败

    我在 RHEL 5 机器上安装了 mono 如下所示 哪个单声道 usr local bin 单声道 mono V Mono JIT 编译器版本 2 10 2 压缩包 2013 年 10 月 16 日星期三 10 33 49 CDT 版权所
  • 无法听取偏好变化?

    class UserViewModel extends ViewModel appPrefs registerOnSharedPreferenceChangeListener preferenceChangeListener private
  • 对“device_show_int()”的调用是 Linux 内核错误吗?

    我首先问了这个问题 如何正确初始化平台驱动程序的属性组 https stackoverflow com q 24618284 32836 并得出函数调用的结论device show int 使用错误的函数原型来这样做 代码问题首先定义str
  • Oracle 中的分组依据与分区依据

    我正在编写一个查询来从 Oracle 仓库中获取记录 它是一个简单的选择查询 在几个表上进行连接 并且我有几个要聚合的列 因此我最终在其余列上使用 Groupby 假设我选择了大约 10 列 其中 5 列是聚合列 所以我需要对其他 5 列进
  • dateTime 抱怨 XSD 验证中的空格 (lxml)

    我正在尝试使用 XSD 验证文档 并且 lxml 抱怨 dateTime 值中的空格 尽管它应该折叠它 我不确定这是否是一种损坏的行为 或者我是否只是指定了 XSD 中的错误 花了一个小时尝试调试这个 所以希望其他人以前也经历过类似的行为
  • 在现有 C 项目中使用 Go 代码

    自从 Go 1 5 发布以来 我开始重新考虑如何将它集成到我现有的项目中 该项目的代码库完全用 C 编写 用于对硬件和其他有趣的东西进行低级访问 然而 一些更高层次的东西很乏味 我想开始用更高层次的语言 Go 来编写它们 有什么方法可以从