接口文件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文件声明的接口了.
接下来重写接口文件:
- 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语言的标准输入输出流函数
-
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节.
-
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文件,我做过尝试,将两个不同的文件声明同一个方法,然后用实现这个方法发现并没有报错,此处怀疑是编译器寻找到声明的函数后直接将函数分成两份重写到不同的声明去,相同包里面的同名函数都将被重写.
有疑问加站长微信联系(非本文作者)