go语言如何移除c代码 go语言import

如何在golang 中调用c的静态库或者动态库Cgo 使得Go程序能够调用C代码. cgo读入一个用特别的格式写的Go语言源文件, 输出Go和C程序, 使得C程序能打包到Go语言的程序包中.
举例说明一下. 下面是一个Go语言包, 包含了两个函数 -- Random 和 Seed -- 是C语言库中random和srandom函数的马甲.
package rand
/*
#include stdlib.h
*/import "C"func Random() int {return int(C.random())}func Seed(i int) {C.srandom(C.uint(i))}
我们来看一下这里都有什么内容. 开始是一个包的导入语句.
rand包导入了"C"包, 但你会发现在Go的标准库里没有这个包. 那是因为C是一个"伪包", 一个为cgo引入的特殊的包名, 它是C命名空间的一个引用.
rand 包包含4个到C包的引用: 调用 C.random和C.srandom, 类型转换 C.uint(i)还有引用语句.
Random函数调用libc中的random函数, 然后回返结果. 在C中, random返回一个C类型的长整形值, cgo把它轮换为C.long. 这个值必需转换成Go的类型, 才能在Go程序中使用. 使用一个常见的Go类型转换:
func Random() int {return int(C.random())}
这是一个等价的函数, 使用了一个临时变量来进行类型转换:
func Random() int {var r C.long = C.random()return int(r)}
Seed函数则相反. 它接受一个Go语言的int类型, 转换成C语言的unsigned int类型, 然后传递给C的srandom函数.
func Seed(i int) {C.srandom(C.uint(i))}
需要注意的是, cgo中的unsigned int类型写为C.uint; cgo的文档中有完整的类型列表.
这个例子中还有一个细节我们没有说到, 那就是导入语句上面的注释.
/*
#include stdlib.h
*/import "C"
Cgo可以识别这个注释, 并在编译C语言程序的时候将它当作一个头文件来处理. 在这个例子中, 它只是一个include语句, 然而其实它可以是使用有效的C语言代码. 这个注释必需紧靠在import "C"这个语句的上面, 不能有空行, 就像是文档注释一样.
Strings and things
与Go语言不同, C语言中没有显式的字符串类型. 字符串在C语言中是一个以0结尾的字符数组.
Go和C语言中的字符串转换是通过C.CString, C.GoString,和C.GoStringN这些函数进行的. 这些转换将得到字符串类型的一个副本.
下一个例子是实现一个Print函数, 它使用C标准库中的fputs函数把一个字符串写到标准输出上:
package print// #include stdio.h// #include stdlib.himport "C"import "unsafe"func Print(s string) {cs := C.CString(s)C.fputs(cs, (*C.FILE)(C.stdout))C.free(unsafe.Pointer(cs))}
在C程序中进行的内存分配是不能被Go语言的内存管理器感知的. 当你使用C.CString创建一个C字符串时(或者其它类型的C语言内存分配), 你必需记得在使用完后用C.free来释放它.
调用C.CString将返回一个指向字符数组开始处的指错, 所以在函数退出前我们把它转换成一个unsafe.Pointer(Go中与C的void 等价的东西), 使用C.free来释放分配的内存. 一个惯用法是在分配内存后紧跟一个defer(特别是当这段代码比较复杂的时候), 这样我们就有了下面这个Print函数:
func Print(s string) {cs := C.CString(s)defer C.free(unsafe.Pointer(cs))C.fputs(cs, (*C.FILE)(C.stdout))}
构建 cgo 包
如果你使用goinstall, 构建cgo包就比较容易了, 只要调用像平常一样使用goinstall命令, 它就能自动识别这个特殊的import "C", 然后自动使用cgo来编译这些文件.
如果你想使用Go的Makefiles来构建, 那在CGOFILES变量中列出那些要用cgo处理的文件, 就像GOFILES变量包含一般的Go源文件一样.
rand包的Makefile可以写成下面这样:
include $(GOROOT)/src/Make.inc
TARG=goblog/rand
CGOFILES=\rand.go\include $(GOROOT)/src/Make.pkg
然后输入gomake开始构建.
更多 cgo 的资源
cgo的文档中包含了关于C伪包的更多详细的说明, 以及构建过程. Go代码树中的cgo的例子给出了更多更高级的用法.
一个简单而又符合Go惯用法的基于cgo的包是Russ Cox写的gosqlite. 而Go语言的网站上也列出了更多的的cgo包.
最后, 如果你对于cgo的内部是怎么运作这个事情感到好奇的话, 去看看运行时包的cgocall.c文件的注释吧.
go语言如何调用c函数直接嵌入c源代码到go代码里面
package main
/*
#include stdio.h
void myhello(int i) {
printf("Hello C: %d\n", i);
}
*/
import "C"
import "fmt"
func main() {
C.myhello(C.int(12))
fmt.Println("Hello Go");
}
需要注意的是C代码必须放在注释里面
import "C"语句和前面的C代码之间不能有空行
运行结果
$ go build main.go./main
Hello C: 12
Hello Go
分开c代码到单独文件
嵌在一起代码结构不是很好看,很多人包括我,还是喜欢把两个分开,放在不同的文件里面,显得干净,go源文件里面是go的源代码,c源文件里面是c的源代码 。
$ ls
hello.chello.hmain.go
$ cat hello.h
void hello(int);
$ cat hello.c
#include stdio.h
void hello(int i) {
printf("Hello C: %d\n", i);
}
$ cat main.go
package main
// #include "hello.h"
import "C"
import "fmt"
func main() {
C.hello(C.int(12))
fmt.Println("Hello Go");
}
编译运行
$ go build./main
Hello C: 12
Hello Go
编译成库文件
如果c文件比较多,最好还是能够编译成一个独立的库文件,然后go来调用库 。
$ find mylib main
mylib
mylib/hello.h
mylib/hello.c
main
main/main.go
编译库文件
$ cd mylib
# gcc -fPIC -shared -o libhello.so hello.c
编译go程序
$ cd main
$ cat main.go
package main
// #cgo CFLAGS: -I../mylib
// #cgo LDFLAGS: -L../mylib -lhello
// #include "hello.h"
import "C"
import "fmt"
func main() {
C.hello(C.int(12))
fmt.Println("Hello Go");
}
$ go build main.go
运行
$ export LD_LIBRARY_PATH=../mylib
$ ./main
Hello C: 12
Hello Go
在我们的例子中 , 库文件是编译成动态库的,main程序链接的时候也是采用的动态库
$ ldd main
linux-vdso.so.1 =(0x00007fffc7968000)
libhello.so = ../mylib/libhello.so (0x00007f513684c000)
libpthread.so.0 = /lib64/libpthread.so.0 (0x00007f5136614000)
libc.so.6 = /lib64/libc.so.6 (0x00007f5136253000)
/lib64/ld-linux-x86-64.so.2 (0x000055d819227000)
理论上讲也是可以编译成整个一静态链接的可执行程序,由于我的机器上缺少静态链接的系统库,比如libc.a , 所以只能编译成动态链接 。
使用go语言还需要写c语言代码吗某语言是否会替代另一种语言,是要看使用场景的 。
如果说全面替代,确实如前所说至少短期内不会,除非Google或者第三方愿意实现一个Go芯片之类的,短期内可以期待的是ChromeOs对Go的依赖和支持,是否会向Qt之于Linux桌面一样 。
但是Go的使用场景跟C的使用场景并不完全一致,它的出现并不是为了取消某种语言,而是为了加速、简化并行编程、服务开发,以及增加很多C、C这种底层语言所难以支持的语言特性 , 让开发更有人性化 。在这一点上,Go是有可能取代C的 。
golang中调用c的正确姿势工程结构如上图所示,我们需要实现的目标是在go文件中调用c文件
foo.c如下:
foo.go如下
foo.h如下:
编译过程如下:
1、先将c文件编译为.o文件,然后生成动态链接库.dylib文件
(1) clang -c foo.c
(2 clang -shared foo.o -o libfoo.dylib
2、在上述的动态链接库生成之后,在foo.go中添加动态链接命令:#cgo LDFLAGS: -L./ -lfoo
需要注意的是
中间不能有空格
matlab下如何除错c函式 zzmatlab下如何除错c函式 zz
double add(double x,double y){ return xy; } MEX档案介面函式 void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) {double *a; double b, c; plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); a = mxGetPr(plhs[0]); b = *(mxGetPr(prhs[0])); c = *(mxGetPr(prhs[1])); *a = add(b, c);}以上已经建立好了add.c档案啦 。然后进行以下步骤: 步1、在matlab命令列 mex -setup,然后选择编译器,我们这选择microsoft的VC6.0. 步2、在matlab命令列输入 mex add.c -output add,这时会产生连结add.mexw32 。如果你是要一个除错版本 , 就在命令列中加上-g开关 。如果你对C/C编译器还有些引数要指定,可以将 /bin/win32/mexopts/msvc60opts.bat拷贝到当前目录下修改之,再加上-f 就行了 。例如:我们这用mex add.c -g -output add,这里除了产生add.mexw32,还有add.ilk,add.pdb 。步3、在cmd下键入msdev 目录\add.mexw32 。现在 , vc打开了,开启你要除错的C/C档案,这个例子中就是add.c,设定好断点 , 按Alt F7,在 Debug表单的Excuitable for debug session中键入D:\Program Files\MATLAB71\bin\win32\matlab.exe(matlab的安装目录)就行了 。按F5,MATLAB就被开启 , 好,可以工作了,在命令列输入add(1,2);然后程式就会在add.c设定了断点的地方中断 。这时只有在VC下除错就行 。^_^
matlab 如何打出ierfc函式
绘制自定义函式的方法至少有两种:一种用plot函式,一种用fplot函式 。以下以y=3x^3-2x 3(0=x=5)为例分别介绍这两种方法 。
方法一:定义向量x和向量y,然后plot画图即可 , 具体程式码:
x=0:0.01:5;
y=3.*x.^3-2.*x 3;
plot(x,y);
结果:
方法二:定义匿名函式f,然后用fplot画图,具体程式码:
f=@(x) 3*x^3-2*x 3;
fplot(f,[0,5]);
结果:
windows下qt4中如何呼叫C函式
应该有很多方法,以下只是其中的一种,用于计算该函式被呼叫次数
void fun()
{
static int count = 0;
count;
coutcount;
}
go语言如何呼叫c函式
直接嵌入c原始码到go程式码里面
package main
/*
#include stdio.h
void myhello(int i) {
printf("Hello C: %d\n", i);
}
*/
import "C"
import "fmt"
func main() {
C.myhello(C.int(12))
fmt.Println("Hello Go");
}
需要注意的是C程式码必须放在注释里面
import "C"语句和前面的C程式码之间不能有空行
执行结果
$ go build main.go./main
Hello C: 12
Hello Go
分开c程式码到单独档案
嵌在一起程式码结构不是很好看,很多人包括我,还是喜欢把两个分开,放在不同的档案里面,显得干净,go原始档里面是go的原始码,c原始档里面是c的原始码 。
$ ls
hello.c hello.h main.go
$ cat hello.h
void hello(int);
$ cat hello.c
#include stdio.h
void hello(int i) {
printf("Hello C: %d\n", i);
}
$ cat main.go
package main
#include "hello.h"
import "C"
import "fmt"
func main() {
C.hello(C.int(12))
fmt.Println("Hello Go");
}
编译执行
$ go build./main
Hello C: 12
Hello Go
编译成库档案
如果c档案比较多,最好还是能够编译成一个独立的库档案,然后go来呼叫库 。
$ find mylib main
mylib
mylib/hello.h
mylib/hello.c
main
main/main.go
编译库档案
$ cd mylib
# g -fPIC -shared -o libhello.so hello.c
编译go程式
$ cd main
$ cat main.go
package main
#cgo CFLAGS: -I../mylib
#cgo LDFLAGS: -L../mylib -lhello
#include "hello.h"
import "C"
import "fmt"
func main() {
C.hello(C.int(12))
fmt.Println("Hello Go");
}
$ go build main.go
执行
$ export LD_LIBRARY_PATH=../mylib
$ ./main
Hello C: 12
Hello Go
在我们的例子中,库档案是编译成动态库的,main程式连结的时候也是采用的动态库
$ ldd main
linux-vdso.so.1 = (0x00007fffc7968000)
libhello.so = ../mylib/libhello.so (0x00007f513684c000)
libpthread.so.0 = /lib64/libpthread.so.0 (0x00007f5136614000)
libc.so.6 = /lib64/libc.so.6 (0x00007f5136253000)
/lib64/ld-linux-x86-64.so.2 (0x000055d819227000)
理论上讲也是可以编译成整个一静态连结的可执行程式 , 由于我的机器上缺少静态连结的系统库,比如libc.a,所以只能编译成动态连结 。
如何除错 Navicat for PostgreSQL 函式
Navicat for PostgreSQL 触发器常规属性:
限制:勾选此项,建立一个限制触发器 。
触发器型别:可供选择的触发器型别有 Table 或 View 。需要注意的是,适用于PostgreSQL 9.0 或以上版本 。
表名或检视名:选择表或检视 。
BEFORE:当尝试在行操作前 , 可以指定触发触发器 。
AFTER:当尝试在行操作后,可以指定触发触发器 。
INSTEAD OF:指定触发触发器来代替尝试在行操作 。
INSERT/UPDATE/DELETE:选择启用触发器的事件 。
插入:每当一个新行插入表 , 触发器会被启用 。
更新:每当修改一个行,触发器会被启用 。
删除:每当从表删除一个行,触发器会被启用 。
TRUNCATE:触发器定义为触发 TRUNCATE 。
更新栏位:指定一个列列表 。如果至少一个列在 UPDATE 命令提及为目标 , 触发器将会触发 。
STATEMENT:指定触发器过程在每个 SQL 语句触发一次 。
ROW:指定触发器过程在触发器事件影响一行时触发一次 。
当:指定一个布林值 WHEN 条件,测试触发器是否应该被触发,该功能支援 PostgreSQL 9.0 或以上版本 。
触发函式模式和触发函式:使用者提供的函式 , 被宣告为没有引数及返回型别触发器 , 当触发器触发时执行 。
函式引数:一个当触发器执行时 , 指供给函式的可选逗号分隔引数列表,引数是文字字串常数 。简单的名和数字常数可以写在这里,但它们都将被转换为字串 。请检查触发函式的实施语言描述,关于如何可访问触发器引数,它可能和正常函式引数不同 。
Navicat for PostgreSQL 触发器限制:
可搁置:可搁置限制 。
最初立即:在每个语句后检查限制 。
最初搁置:只在事务结束时检查限制 。
参考表模式和参考表名:限制参考表的模式和名 。
【求助】matlab如何求解sinc函式的反函式
for k=1:length(y)
f=@(x)y(k)*x-sin(x);
ezplot(f);%画图,观察函式零点在x0(k)附近
z(k)=fzero(f,x0(k));%呼叫fzero函式找零点
endsxf2012(站内联络TA)%%以y为一个数据为例 , 假设y值为y0,则令
%f=@(x)y0-sin(x)/x;%%用命令:%ezplot(f);
%%画图,观察函式 , 随便找零点附近的一个座标x0
%% 则,要求的零点为
%z=fzero(f,x0);%呼叫fzero函式找零点
%比如y0=0.6,通过令
f=@(x)0.6-sin(x)/x;%画图ezplot(f)hold onplot(,,'r')
%观察知,零点在-2和2附近,用
z1=fzero(f,-2)
%计算得零点为x=-1.66
z2=fzero(f,2)
%计算得零点为x=1.66
这是y=sinx/x的曲线图 。我的情况是y的值是已知的,我需要把x的全部值求出来,即想通过反函式来求得 。但是问题是,y=1时x是一个值,但y=0.8是两个值,y=0.1就是许多值 。
这是y=sinx/x的曲线图 。我的情况是y的值是已知的,我需要把x的全部值求出来 , 即想通过反函式来求得 。但是 ... 在你画的区间上,函式不是单调的,所以其反函式不存在的,或者说是个多值函式 。
51微控制器汇编如何呼叫C函式?
先宣告,后调出 。
若C语言函式名为ABC,汇编的入口符号为_ABC 。
例:CALL _ABC , 就呼叫的了ABC涵数 。
至于如何宣告,如何传函式引数,就要查编译器的使用说明了 。
我也没这么做过 , 一般是高阶语言呼叫低阶语言,只是一个建议 。
matlab 的plotroc函式怎么呼叫
matlab 的plotroc函式主要是绘制ROC曲线 。
ROC曲线是通用的分类器评价工具,matlab函式中自带了绘制该曲线的函式plotroc 。
plotroc函式的原型为:plotroc(targets, outputs)
其中引数targets是一个矩阵 , 代表测试集,每一列表示一个测试样本的标签
如果有两类样本,比如第1,2,5个样本属于第1类,第3,4,6个样本属于第2类....则targets应为:
1 1 0 0 1 0 ...
0 0 1 1 0 1 ...
如果只有一类样本,包含了负样本,则只要一行,用1表示正样本,0表示负样本即可,比如targets为:
1 0 1 1 0 0 0 0 1 ...
引数outputs也是一个矩阵,代表分类结果,同样每一列表示一个测试样本的分类结果
同样如果有两类样本,则应有两个分类器,每一列记录了每个测试样本在两个分类器上的得分,此时outputs为:
0.8 0.85 0.2 0.75 0.21 ...
0.8 0.01 0.9 0.23 0.67 ...
如果只有一类,则outputs只有一行,如:
0.8 0.6 0.8 0.7 0.05 0.3 0.03 ...
注意,得分必须在[0, 1]的区间内,可以自己规约一下 。
我们将相应的测试标签targets和对应的分类得分outputs输入plotroc中就可以绘制出相应的ROC曲线了 。
有人问起,我也就在网上搜了一下,发现还有很多人不会用,写下来以供参考,欢迎指正 。
如何除错Android SO中的init函式
1.Root装置
Root许可权下才能快乐除错 。
使用市面上的各种Root师傅工具 。
2.连线装置
将装置开启除错模式在开发者选项里 。
将IDA安装目录中dbgsrv资料夹下的android_server推送到装置系统目录并赋可执行许可权 。在高于IDA6.6版本才能除错高版本android,此时除错低版本Android SO时,需要使用的是android_nonpipe 。
在PC端输入命令:
adb shell su
adb shell android_server的路径/android_server
保持上面视窗,在命令列视窗进行埠转发:
adb forward tcp:23946 tcp:23946
为什么是23946呢,IDA和push进装置的android_server预设用都用23946埠进行通讯 。当然可以修改 。
3.开启IDA
附加或者启动程序的过程不再多言 。
4.定位INIT函式
比较便捷的方法是找一份与装置同系统版本号的android原始码 。解析执行SO档案的地方在linker.c(cpp)中 。
因为不同版本有差异,我就不上图了 。
高版本时在do_dlopen()下的CallConstructors()里面,但是编译系统时往往将其和find_library融合在其父函式中,查询时需注意 。一个简便方法是原始码中搜索“INIT”四个字.
先将装置中的linker pull出来用IDA分析来确定呼叫INIT的具 *** 置 。
因为linker在Android程序中载入非常早,所以它在IDA中的地址可以不用修正直接拿来用 。
5.下断在INIT
下断点后,执行Apk中触发载入该SO的功能 。
正常情况下就能停在该SO的INIT前了 。
如何在QT中写C函式?
/********MyButton.h*********/
#ifndef MYBUTTON_H_
#define MYBUTTON_H_
#includeiostream
#include QtGui/QPushButton
#include QtGui/QWidget
class MyButton : public QPushButton
{
Q_OBJECT
【go语言如何移除c代码 go语言import】public:
MyButton(const QStringtext, QWidget * parent);
~MyButton();
public:
void setLed(int argc, char *argv[]);
public slots:
void sendButtonText();
private:
signals:
void isClickButton(const QString text);
};
#endif
[cpp] view plain copy
/**********MyButton.cpp************/
#include "MyButton.h"
extern "C"{
#include stdio.h
#include stdlib.h
#include unistd.h
#include sys/ioctl.h
#includesys/types.h
#includesys/stat.h
#includeftl.h
void MyButton::setLed(int argc, char *argv[]){
int on;
int led_number;
int fd;
if (argc != 3 || sscanf(argv[1], "%d", led_number) != 1 || sscanf(argv[2],"%d", on) != 1 ||
on0 || on1 || led_number0 || led_number3) {
fprintf(stderr, "Usage:\n");
fprintf(stderr, "\t led led_number on|off\n");
fprintf(stderr, "Options:\n");
fprintf(stderr, "\t led_number from 0 to 3\n");
fprintf(stderr, "\t on 1 off 0\n");
exit(1);
}
fd = open("/dev/led", 0);
if (fd0) {
perror("open device /dev/led");
exit(1);
}
ioctl(fd, on, led_number);
::close(fd); 请注意,此处如果要呼叫C语言库中的close()一定要加上“::",否则程式将到当前类的作用域中寻找close()方法 , 导致不明错误 。
}
}
MyButton::MyButton(const QString text,QWidget *widget)
:QPushButton(text,widget)
{
connect(this,SIGNAL(clicked()),this,SLOT(sendButtonText()));
}
MyButton::~MyButton()
{
}
void MyButton::sendButtonText(){
emit isClickButton(this-text());
char open_1[]="1";
char open_2[]="1";
char open_3[]="1";
char *o1=open_1;
char *o2=open_2;
char *o3=open_3;
char close_1[]="1";
char close_2[]="1";
char close_3[]="0";
char *c1=close_1;
char *c2=close_2;
char *c3=close_3;
char *open[]={o1,o2,o3};
char *close[]={c1,c2,c3};
QString *str=new QString(this-text());
if((str-pare("mb1"))==0){
std::cout"mb1 is clicked!\n";
setLed(3,open);
}
if((str-pare("mb2"))==0){
std::cout"mb2 is clicked!\n";
setLed(3,close);
}
}
go语言如何移除c代码的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于go语言import、go语言如何移除c代码的信息别忘了在本站进行查找喔 。

    推荐阅读