golang cgo不能通过构建模式c-shared导出变量

时间:2016-03-25 00:27:09

标签: go cgo

我正在尝试在cgo中开发一个sudo的插件。

https://www.sudo.ws/man/1.8.15/sudo_plugin.man.html

将struct导出到policy_plugin的全局范围。

  

策略插件必须在全局范围内声明并填充policy_plugin结构。

你对这意味着什么有解释?

export_test.go

package main

/*
#include "sudo_plugin.h"
#include <stddef.h>
*/
import "C"

func main() {
}

// don't worked
//export policy
var policy = &C.struct_policy_plugin{
    C.SUDO_POLICY_PLUGIN,
    C.SUDO_API_VERSION,
    nil,
    nil,
    nil,
    nil,
    nil,
    nil,
    nil,
    nil,
    nil,
    nil,
}

1 个答案:

答案 0 :(得分:0)

看起来buildmode c-shared只导出函数条目,而不是变量。 虽然the design doc没有明确说明,但它也没有明确地谈论变量。

cmd/cgo manual也未明确提及变量,但似乎暗示特殊//export ...注释仅适用于函数。

你应该做的就是在C方面声明你的外部变量 - 在定义和表达必要的Go函数之后,如下所示:

&#34; callbacks.go&#34;:

package main

import "C"

//export real_fn
func real_fn(x C.int) C.int {
    return 42
}

&#34; main.go&#34;:

package main

/*
typedef struct {
    int x;
    int (*fn) (int x);
} foo;

extern int real_fn(int);

foo xyzzy = {
    0,
    real_fn,
};
*/
import "C"

func main() {
}

现在运行go build -buildmode=c-shared后,您可以浏览生成的库并查看其中提供的xyzzy符号:

cshared% nm -g cshared | grep -E 'xyzzy|real_fn'
0000000000061330 T _cgoexp_4f8dd74b8333_real_fn
00000000000b42c0 T real_fn
00000000003274d0 D xyzzy

注意:如果您要使用回调,则必须将它们放入单独的文件(或文件)中 - 这似乎是cgo的怪癖。