快上网专注成都网站设计 成都网站制作 成都网站建设
成都网站建设公司服务热线:028-86922220

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

go中使用c语言静态库,go 静态库

C语言中静态库和动态库的区别,如何使用它们

一般C语言写的程序可以让其他语言进行调用,比如python, java,等等

成都创新互联公司2013年成立,是专业互联网技术服务公司,拥有项目网站设计制作、成都做网站网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元舟山做网站,已为上家服务,为舟山各地企业和个人服务,联系电话:028-86922220

c语言有两种库类型,静态库和动态库(共享库)

命令:ar rcs libmulib.a file1.o

C语言vs怎么使用自己做的静态库与动态库,本人小白,请求详解

1.静态链接库

打开VS2010,新建一个项目,选择win32项目,点击确定,选择静态库这个选项,预编译头文件可选可不选。

在这个空项目中,添加一个.h文件和一个.cpp文件。名字我们起为static.h和static.cpp

static.h文件:

[cpp] view plaincopy

#ifndef LIB_H

#define LIB_H

extern "C" int sum(int a,int b);

#endif

static.cpp文件:

[cpp] view plaincopy

#include "static.h"

int sum(int a,int b)

{

return a+b;

}

编译这个项目之后,会在debug文件夹下生成static.lib文件,这个就是我们需要的静态链接库。

下面说明如何调用静态链接库。

首先需要新建一个空项目,起名为test。将之前static项目下的static.h和static.lib这个2个文件复制到test项目的目录下,并在工程中加入static.h文件。

新建一个test.cpp文件如下:

[cpp] view plaincopy

#include stdio.h

#include stdlib.h

#include "static.h"

#pragma comment(lib,"static.lib")

int main()

{

printf("%d\n",sum(1,2));

system("pause");

return 0;

}

编译运行可得结果:3

#pragma comment(lib,"static.lib"),这一句是显式的导入静态链接库。除此之外,还有其他的方法,比如通过设置路径等等,这里不做介绍。

2.动态链接库

和创建静态链接库一样,需要创建一个空的win32项目,选择dll选项。创建dynamic.cpp和dynamic.h文件

dynamic.h文件:

[cpp] view plaincopy

#ifndef DYNAMIC

#define DYNAMIC

extern "C" __declspec(dllexport)int sum(int a, int b);

#endif DYNAMIC

dynamic.cpp文件:

[cpp] view plaincopy

#include "dynamic.h"

int sum(int a, int b)

{

return a+b;

}

编译这个项目,会在debug文件夹下生成dynamic.dll文件。

下面介绍如何调用动态链接库,这里讲的是显式的调用。

在刚才的test项目下,把static.lib和static.h文件删除,把dynamic.h和dynamic.dll复制到该目录下,并在项目中添加dynamic.h文件,修改test.cpp文件为:

[cpp] view plaincopy

#include stdio.h

#include stdlib.h

#includeWindows.h

#include "dynamic.h"

int main()

{

HINSTANCE hDll=NULL;

typedef int(*PSUM)(int a,int b);

PSUM pSum;

hDll = LoadLibrary(L"dynamic.dll");

pSum = (PSUM)GetProcAddress(hDll,"sum");

printf("%d\n",pSum(1,2));

system("pause");

FreeLibrary(hDll);

return 0;

}

编译运行结果为:3

特别提示:

1.extern "C"中的C是大写,不是小写

2.如果从VS2010中直接运行程序,lib和dll需要放到test项目的目录下;如果想双击项目test下的debug文件中的exe文件直接运行的话,需把lib和dll放入debug文件夹下。

C语言里面的动态库和静态库

之所以成为【静态库】,是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。

试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。静态库特点总结:

为什么需要动态库,其实也是静态库的特点导致。

动态库特点总结:

生成动态库

请教高手教一下用gcc编译c语言函数,再合并为静态库,最后调用的过程。

应该编译成.a文件

ar rc c:\libab.a c:\a.o c:\b.o

然后,再编译执行文件

gcc -o c:\m.exe c:\m.c -LC:\ -lab

你这样试试

如何在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.h import "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文件的注释吧.

C语言调用静态库显示"不是内部或外部命令,也不是可运行的程序或批处理文件"

你通过VS调试运行程序的时候默认会去查找程序目录下面的Debug中的和项目同名的exe文件(你的情况是TEST.exe)。因为你编译失败了,exe文件没有生成所以找不到这个文件去执行。你目前的情况看来是你尝试用C的编译器去编译C++代码(因为你创建的是.c文件)所以失败。把文件名改成cpp重新编译再试


文章名称:go中使用c语言静态库,go 静态库
分享路径:http://6mz.cn/article/hcsdii.html

其他资讯