C语言生成dll与lib文件

C语言生成dll与lib文件

环境要求

新建一个空白项目,可以是exe的,也可以直接是dll的,也可以是啥都没有的空项目,推荐创建空项目,项目创建好以后进行配置,共两步

第一步,打开项目属性

第二步,设置配置类型为动态库dll,并确定

编写dll库函数

test1.c

_declspec(dllexport) int test(int a, int b)

{

return a + b + b;

}

test1.h

#pragma once

_declspec(dllexport) int test(int a, int b);

test2.c

_declspec(dllexport) int minus(int a, int b)

{

return a - b;

}

test2.h

#pragma once

_declspec(dllexport) int minus(int a, int b);

常见问题和错误说明

声明,下述结论以测试工程为例:

1. 编写dll库不需要main函数,直接写函数即可,参考工程见下图1;

2. 生成的dll文件保存路径如下:H:\Test\x64\Debug;

3. 生成成功的标志(图2),只要输出窗口中显示1成功即可,不用理会白色的报错;

4. 如果输出窗口中没有字(图3),那么前往 H:\Test\x64\Debug;把里面所有文件删了再重新编译运行即OK;

5. 如果上述都不行,那么点击 生成 --> 重新生成解决方案;

6. 编写函数时,一定要加上 _declspec(dllexport) ,不然dll文件可以正常生成,但是Python读取不了;

7. 只写.c文件,不写.h文件,生成的dll文件python一样可以调用,不建议这么干;

8. lib和dll文件详细说明后附;

9. 加上 _declspec(dllexport) ,会生成 lib 文件和 dll 文件,不加只会生成dll文件;

10. 如果工程下存在多个.c和.h文件,里面都存放了函数,随便点哪里编译运行即可,生成的dll文件会包含所有.c的函数;

11. 无法看到dll文件中有哪些函数,想看的话可以通过小工具 dll export viewer;

12. 有时候头文件中会通过 extern "C" _declspec(dllexport) int minus(int a, int b); 来创建函数,

是因为如果按照C的方式来创建,在dll经过编译器后函数名不会变,否则会被编译器修饰,例如C++调用dll时。

Python调用dll文件

Python调用dll时,只需要dll文件

import ctypes

a = ctypes.CDLL('Test.dll')

ret = a.test(1,2)

ret1 = a.miuns(1,2)

print(ret, ret1)

C语言调用dll文件

静态调用

1. 静态调用需要lib文件和dll文件,在程序一开始执行时就加载这个文件。

2. 在调用前,先把lib和dll拷贝到当前工程文件夹,不然提示找不到dll,见下图。

3. 在下面示例中,我没有声明 test 函数,但是它依然可以正常调用,是因为C会假设它存在,并执行相应操作,

但是这种方式不可以取,在调用时,还是显式声明一下。

#include

#include

#include

#pragma comment(lib, "H://Test//x64//Debug//Test.lib") // 通过关键字导入静态文件路径

_declspec(dllimport) int minus(int a, int b); // 声明导入函数,注意这里是import

int main() {

int a = minus(5, 6);

int b = test(5, 6);

printf("%d", a);

printf("%d", b);

}

动态调用

1. 动态调用是比较常用的一种方法。

2. dll文件可以通过直接指定路径的方式来添加。

3. 动态调用是什么时候用dll,什么时候再加载dll。

4. 流程: 实例一个句柄 --> 创建指向函数地址的指针 --> 获取函数入口地址 --> 使用函数

#include

#include

#include

int main()

{

HINSTANCE h = LoadLibrary(L"H://Test//x64//Debug//Test.dll"); // 实例化句柄

typedef int (*p_func)(int a, int b); // 创建一个指向函数地址的指针

p_func testfunc = (p_func)GetProcAddress(h, "test"); // 获取函数入口地址

int a = testfunc(5, 6);

printf("%d", a);

return 0;

}

dll和lib的详细介绍

lib 分为两种

第一种包含了函数所在的dll文件和文件中函数入口,具体的代码由运行时dll来提供。第二种时lib包含了代码本身,在编译时直接把代码加入到程序中。

区别

lib是编译时才用,dll是运行时才用。完成源代码编译只需lib,程序要跑起来需要用到dll。如果存在dll文件,那么lib中一般是一些索引信息,记录函数的入口和位置,dll中是具体内容。如果只有lib,那么这个lib是静态编译出来的,索引和代码都在里面。如果使用静态编译的lib,那么编译时程序会全部加载到项目中,会使应用程序超级大,并且失去了动态库的灵活性,发布新版本需要发布新的应用程序。如果不想使用lib文件,可以同win32 API提供的Loadbriary,GetProcAddress来直接调用dll。

注意事项

头文件中包含lib中说明输出的符号和数据结构,应用程序调用lib时,需要将头文件包含进去。包含了dll中说明输出的符号和数据结构的.h文件,应用程序调用dll时,应该将.h文件引入应用程序的源文件中。

开发成功后的应用程序在发布时,只需要.exe和.dll文件,并不需要.lib和.h文件。

相关推荐

青青的什么 例:青青的小草 ?
365资讯下载安装

青青的什么 例:青青的小草 ?

📅 07-21 👁️ 3124
梦幻西游灵饰怎么获得2025
正规365网址是多少

梦幻西游灵饰怎么获得2025

📅 07-27 👁️ 7254
《冒险岛》秘笈揭秘 神秘石的妙用大解析
365资讯下载安装

《冒险岛》秘笈揭秘 神秘石的妙用大解析

📅 09-09 👁️ 8837