Windows 7 上动态库开发
来源:互联网 发布:知乎怎样发表文章 编辑:程序博客网 时间:2024/05/16 06:04
准备工作:
建立文件夹F:\pule
以后所有操作都在文件夹pule中
建立好的文件夹视图。
其中puleDll作为Dll开发目录
puleMain则是Main函数,调用puleDll中的函数来测试。
DLL工程的建立
1.创建puledll工程,
打开VC6.0, 文件-->新建-->工程,选择win32 dynamic-Link Library, 左边填写文件名pule: 如下图
确定之后,选择“一个可以导出某些符号的dll工程”, 再点击 完成---确定(如下图)
2此时查看工作空间,如下:
我们要做纯C开发,所以,把这里的CPP后缀全部改成.c,; 也就是把pule.cpp 改成pule.c
而且不需要预编译头,也就是删除StdAfx.h 和StdAfx.cpp
此时的工作空间如下:
这时编译是过不了的,出现:f:\pule\puledll\pule\pule.c(4) : fatal error C1083: Cannot open precompiled header file: 'Debug/pule.pch': No such file or directory错误
这是因为我们删除了预编译头文件,也就是stdafx.h 和stdafx.cpp, 只需要设置下工程选项:
工程-->设置-->c/c++
在c/c++标签下,“分类” 中选择预编译的头文件, 选择 “不使用预补偿页眉", 确定就可以了。
此时再编译还是过不了:
这是因为我们把pule.cpp后缀编成了.c, 由于VC认为以.c为后缀的是纯C代码, C语言是没有类的, 所以, pule.h 定义的那个类就有问题了,解决此问题的方法 就是直接删除关于类的定义。
删除之后的代码如下:
pule.h:
#ifdef PULE_EXPORTS#define PULE_API __declspec(dllexport)#else#define PULE_API __declspec(dllimport)#endifextern PULE_API int nPule;PULE_API int fnPule(void);
pule.c
// pule.c : Defines the entry point for the DLL application.//#include "pule.h"#include <windows.h>BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break; } return TRUE;}// This is an example of an exported variablePULE_API int nPule=0;// This is an example of an exported function.PULE_API int fnPule(void){return 42;}
可以看出上面还加了一行#include<windows.h>
开发win32程序当然得包含windows.h了, 以前这个文件是包含在stdafx.h中的, 现不需要这个文件,所以就得自己包含windows.h了
完成以设置后,点击生成,就会在pule\debug\中生成pule.dll和pule.lib
3.动态链接库制作与链接原理:
可以看到,要想让动态链接库里的函数能被其他程序调用,必需在声明作如下声明:
PULE_API int fnPule(void);PULE_API是必要的, 以后自己写的函数,想导出,就要依照这个写。
再看生成的文件:
pule.dll就是动态链接库了, 这个库里是程序代码, 编译好的二进制形式。
再看pule.lib, 这个不是静态库, 是编译时需要的库。
如果在另一个程序中调用pule.dl中的函数, 则在链接时需要函数信息,这些信息放在pule.lib中,链接完成后,这个库就没用了, 只要pule.dll就可以运行程序。
测试程序puleMain工程的建立
建立这个工程的目的是调用上一个工程的dll中的函数,以测试上一个工程是不是能正确运行
这个工程是一个普通的win32 Console Application工程
1.创建puleMain工程
打开VC6.0: 文件-->新建-->工程-->win32 Console Application
建立好工程后,再新建一个puleMain.c文件,加入工程中:
文件-->新建-->文件-->C++ Source File ; 文件名取puleMain.c 注意,必须是.c
建立好文件之后,写一个hello world程序, 测试是不是可以正常运行:
如果正常运行就没有问题了。
在测试工程中调用dll工程中的函数:
1.把dll工程的输出目录改为测试工程的输出目录:
现在可以看到,有两个Debug目录:
分别是puledll\pule\debug
pulemain\pulemain\debug
如果puleMain.exe中使用了动态连接库pule.dll, 则pule.dll必须和puleMain.exe在同一个目录中(也有其他方法,把pule.dll入在c:\windows\system32中).
在puledll工程中做如下设置,让此工程编译链接时把pule.dll,pule.lib自动生成到pulemain]pulemain\debug中:
在puledll工程中:工程-->设置-->常规-->输出目录:..\..\puleMain\puleMain\Debug
这时再编译生成puledll工程,打开测试工程的Debug目录,可以看到已经有了pule.dll和pule.lib
2.在测试工程puleMain中调用pule.dll中的fnPule();函数
这是需要添加pule.h头文件
#include<stdio.h>#include"..\..\puleDll\pule\pule.h" //加上头文件int main(){printf("%d\n", fnPule()); //调用dll函数printf("Hello world!\n");return 0;}
此时编译链接会失败,回为链接时找不到fnPule()的定义
再设置链接器选项:工程-->设置-->连接:选择“分类"的常规, 在对象/库模块中加入Debug\pule.lib
也就是在puleMain\puleMain\Debug\中要有pule.lib, 这个在上几步中已经生成了。
确定之后,编译运行应该没有错误了,运行了如下:
可以看到输出了42,表示运行成功了。
在puledll中使用netsnmp的库进行开发
准备工作:
在puledll文件夹下建立net-snmp文件夹,把net-snmp编译安装开发版的库和头文件复制到这个文件夹下
这个需要编译安装net-snmp-5.7.2. 安装时选择安装开发库,这时会在C:\usr下有lib和include两个目录。copy到这里。
可以看到lib文件夹下有四个库, netsnmp.lib netsnmpagent.lib netsnmpmibs.lib netsnmptrapd.lib
以下所有操作均在puledll项目中操作:
在pule.c中加入以下头文件:
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/utilities.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/library/snmp_transport.h>
并且在 int fnPule(void)函数中调用了init_snmp("snmpapp");
// pule.c : Defines the entry point for the DLL application.//#include "pule.h"#include <net-snmp/net-snmp-config.h>#include <net-snmp/utilities.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include <net-snmp/library/snmp_transport.h>BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break; } return TRUE;}// This is an example of an exported variablePULE_API int nPule=0;// This is an example of an exported function.PULE_API int fnPule(void){init_snmp("snmpapp");return 42;}
这些头文件是开发snmp的必要头文件,加入后编译将会产生很多错误, 下面一一解决
1.第一个错误是找不到以上几个头文件:
设置头文件搜索路径:
在工程-->选项-->c/c++:分类:常规中
下边有: 工程 选项, 在最后加入 /I../net-snmp/include
这是告诉编译器到../net-snmp/include目录中查找头文件
在准备工作我们已经将对应的头文件复制到net-snmp目录中了,所以这样设置就可以找到头文件了。
2.出现许多redifinition错误:
看到有ws2tcpip.h有重复定义, 这时要去掉#include<windows.h>
再做如下修改:
PULE_API int fnPule(void)
{
init_agent("snmpagent");
return 42;
}
在这个函数中加入init_agent("snmpagent")
3.链接错误:找到不init_agent
这是因为在链接时找不到init_agent,这个函数在准备工作时复制的那4个库中, 所以这次需要修改链接选项:
工程-->设置-->连接:分类:输入
在附加库路径中加入: ..\net-snmp\lib
在工程选项中加入以下4个库:netsnmp.lib netsnmpagent.lib netsnmpmibs.lib netsnmptrapd.lib
4.MSVCRT.lib(MSVCRT.dll)与LIBCMTD.lib冲突
此时只需要取消默认连接的库LIBCMTD.lib
原因是使用多线程的库msvcrt.lib中有好多函数在单线程的libcmtd.lib中也有,所以只留下一个库msvcrt.lib就可以了:
操作方法:工程-->选项-->连接-:分类:输入:
在忽略库中加入:libcmtd.lib
5.没有连接winsocket相关的库:
解决方法:
链接选项中加入WS2_32.LIB库
操作方法:工程-->选项-->连接-:分类:输入:
在工程选项中加入ws2_32.lib
至次所有错误都已经排除,应该可以生成dll了。
在测试工程puleMain中运行:得到如下结果,可以看出init_snmp("snmpapp")正确运行了。
注意:不要包含stdafx.h头文件。
这以后就可以使用net-snmp提供的4个库进行snmp开发了。
如何自成snmp中的这四个库以及开发所需要的头文件,见我的另一片博文。
注意2:使用net-snmp的四个库, 必须要有MIB, 默认MIB位置在:
C:\usr\share\snmp\mibs
需要根据自己编译安装net-snmp选择位置安装MIB.
- Windows 7 上动态库开发
- 【C/C++开发】C++静态库与动态库以及在Linux和Windows上的创建使用
- Windows Embedded Compact 7 数据库开发(上)
- Windows上开发IOS
- 动态库cp到开发板上的问题
- Windows上的UDF开发
- windows 上开发Apache 模块
- Windows上开发iphone app
- Windows下php扩展开发c++动态库
- 在 Windows Vista、Windows 7 和 Windows Server 2008 上设置 SharePoint 2010 开发环境
- windows动态链接库
- windows 动态链接库
- windows动态库回顾
- windows动态链接库
- windows 动态链接库
- Windows Mobile开发之动态调用WebServcie
- Qt开发:windows下发布动态编译程序
- 在Windows 2003,XP上安装Windows Phone 7开发工具
- Android图像处理之GPUImage for Android
- Linux如何退出VI编辑器
- HC05 蓝牙模块常见问题
- Linux下查看文件常用命令—cat,more,less,head,tail
- python 创建二维数组
- Windows 7 上动态库开发
- 第三周编程作业2 数字特征值
- 多表连接查询(内,外,交叉连接)
- 圆角边框,渐变背影的TextView
- win7系统中ip地址如何确保不被修改
- Linux tail 命令详解
- 学习django的心得与记录
- C链表实现约瑟夫环
- linux 安装软件的几种方法