cgo:不同语言重写hpp文件中声明的函数

繁黎_8086 · · 725 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

引用自golang高级编程2.1节

接口文件hello.h是hello模块的实现者和使用者共同的约定,但是该约定并没有要求必须使用C语言来实现接口。我们可以用不同语言来重新实现这个C语言函数.也是说我们可以使用不同语言不同语法来实现这个功能,只要这个功能被重写即可.

.h文件接口内容:

<pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang="hpp" contenteditable="false" cid="n117" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: normal; display: block; break-inside: avoid; text-align: left; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(223, 226, 229); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">void SayHello(const char* s);</pre>

main文件内容:

<pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang="go" contenteditable="false" cid="n203" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: normal; display: block; break-inside: avoid; text-align: left; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(223, 226, 229); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package main

//#include"hello.h"
import (
"C"
)

func main() {
C.SayHello(C.CString("Hello, World\n"))
}</pre>

使用//#include"hello.h"来import进来c的头文件hello.h.注意这里必须在import语句上面定义且不能有空行,否则编译器会报错.

使用import "C"来引入c编译器,接下来便可以使用.h文件声明的接口了.

接下来重写接口文件:

  1. c语言实现

<pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang="c" contenteditable="false" cid="n74" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: normal; display: block; break-inside: avoid; text-align: left; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(223, 226, 229); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// hello.c

include "hello.h"

include <stdio.h>


void SayHello(const char* s) {
puts(s);
}</pre>

#include "hello.h"导入要重写的接口

#include <stdio.h>导入c语言的标准输入输出流函数

  1. c++实现

    <pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang="cpp" contenteditable="false" cid="n169" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: normal; display: block; break-inside: avoid; text-align: left; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(223, 226, 229); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">// hello.cpp

    include <iostream>


    extern "C" {

    include "hello.h"

    }

    void SayHello(const char* s) {
    std::cout << s;
    }</pre>

我们需要通过extern "C"语句指示该函数的链接符号遵循C语言的规则。此处引用golang高级编程2.1.4节.

  1. go实现

    <pre spellcheck="false" class="md-fences md-end-block contain-cm modeLoaded" lang="go" contenteditable="false" cid="n191" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: normal; display: block; break-inside: avoid; text-align: left; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(223, 226, 229); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">//hello.go
    package main

    import "C"
    import "fmt"

    //export SayHello
    func SayHello(s *C.char) {
    fmt.Print(C.GoString(s))
    }
    ​</pre>

    我们通过CGO的//export SayHello指令将Go语言实现的函数SayHello导出为C语言函数。此处引用golang高级编程2.1.5节.这里没有指定重写的.h文件,我做过尝试,将两个不同的文件声明同一个方法,然后用实现这个方法发现并没有报错,此处怀疑是编译器寻找到声明的函数后直接将函数分成两份重写到不同的声明去,相同包里面的同名函数都将被重写.


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:繁黎_8086

查看原文:cgo:不同语言重写hpp文件中声明的函数

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

725 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传