热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[原创]VC6中调用.dll文件中的函数——傻瓜式教程

作者:周智鹏QQ:39188043您可以任意转载此文章,但请注明出处和作者如果你想快速查看调用.dll文件中函数的方法,请直接从“开始”看起。照例,首先是一段废

作者:周智鹏

QQ:39188043

 

您可以任意转载此文章,但请注明出处和作者

 

如果你想快速查看调用.dll文件中函数的方法,请直接从“开始”看起。

 

照例,首先是一段废话化:
花了尽两天时间,我终于搞清楚如何调用dll文件中的函数了,兴奋之情易于言表啊,这里首先感谢下史磊同学,还有百度上认识的whu_yang兄,感谢你们对我在解决这一问题上的帮助。
先声明下,我此前从未涉及过Windows下的编程,所以对于懂了这么点东西就要写篇文章,大家可不要鄙视啊。
实际上,写这篇文章的最主要原因是,我觉得调用.dll文件里的函数应该是个很简单,很常规的用法,可是遗憾的是,我就查这么点东西,可以说是费尽了周折,足足耗了将尽两天的时间在网上“漫游”,到是也有很多人写过类似的东西,但是,很遗憾,也许是因为他们觉得的太简单而不想多罗嗦吧,我到最后愣是没有找到能看懂的。难道像我这样的初学者,就为了搞清楚这么一点东西,还要系统的学一遍Windows不成?!

 

You Must:
似乎只要懂得基本的C语言就能看懂这篇文章了吧。
本文主要写给,像我这样的,很少编写Windows下程序的程序员或者工程师们的。因此你不需要懂得Windows,不需要懂得VC6,只要知道基本的C就够了。

 

Total:
看了很多文章,包括MSDN上得文档,讲了很多关于dll的东西,一会儿有连什么API呀、COM呀、MFC呀的都出来了。晕~真晕,我就是想知道怎么调用.dll文件里的函数,真的有这么难吗?在这里,我不想拷贝粘贴有关“隐式链接”“显式链接”的概念,我只想分下面两种情况讲解:

开始

一、对于已有.lib和.h文件的情况
  (一)为了方便读者亲自验证与学习,这里首先带领大家建立一个带有.lib和.h的.dll文件

    1.首先打开VC6,File=>New,在Projects选项卡中选"Win32 Dynamic-Link Library",在Project name中输入"DLL_1",在Location中输入"D:/DLL_1",然后单击ok按钮。

    2.选择"A DLL that exports some symbols"项后单击Finish按钮。

    3.单击ok按钮,来确认你新建的项目。

    4.工程建好后,首先要按下F7链接一下。不首先做这一步的话编译时会报错。

    5.

 

    单击图中最下面的FileView选项卡,双击打开Source Files文件夹下的DLL_1.cpp文件。

    6.请看这几行代码,实际上这是VC6自动为我们生成的几个范例,包括一个变量、一个函数和一个类,他们就是最终生成.dll文件后可以被调用的东东。

// This is an example of an exported variable
DLL_1_API int nDLL_1=0;

// This is an example of an exported function.
DLL_1_API int fnDLL_1(void)
{
 return 42;
}

// This is the constructor of a class that has been exported.
// see DLL_1.h for the class definition
CDLL_1::CDLL_1()
{
 return;
}
我们将这几行范例通通删掉,替换为我们自己的代码:

DLL_1_API int fTest()
{
 return 253;
}

    7.双击打开上图中Header Files文件夹下的DLL_1.h文件,逐一看这些代码:

// This class is exported from the DLL_1.dll
class DLL_1_API CDLL_1 {
public:
 CDLL_1(void);
 // TODO: add your methods here.
};

extern DLL_1_API int nDLL_1;

DLL_1_API int fnDLL_1(void);

这些实际上就是上面提到的三个范例的生命,当然我们把它替换成我们的代码:

DLL_1_API int fTest(void);

    8.好了,接下来我们直接F7,然后再看看你的"D:/DLL_1/Debug"目录,怎样?是不是看到了我们可爱的DLL_1.dll和DLL_1.lib文件?而DLL_1.h文件则在"D:/DLL_1"目录中了。

 

  (二)接下来,我们就来实现调用.dll文件中的int fTest()函数。

    1.首先我们关闭刚刚做好的工程。File=>Close Workspace,然后单击“是(Y)”按钮,保存我们刚才所做的一切。

    2.我们新建一个控制台工程File=>New,在Projects选项卡里选"Win32 Console Application",Project name中输入EXE_1,在Location中输入D:/EXE_1,然后单击ok按钮。然后,确认选中"An empty project"后,单击Finish按钮。然后单击ok按钮确认。

    3.下面新建一个.cpp文件:File=>New,在Files选项卡中,选择"C++ Source File",在File中输入Main,单击ok按钮。

    4.在Main.cpp文件中输入下面的代码:

#include "iostream.h"
#include "DLL_1.h"

void main()
{
 int a;
 a = fTest(); //这个就是我们调用的dll文件中的函数了
 cout<}

    5.在编译链接之前,我们还要做一些工作:

     a.把上文提到的DLL_1.h、DLL_1.dll和DLL_1.lib复制到"D:/EXE_1"目录下

     b.Project=>Settings...

在Link选项卡中的"Object/library modules:"的最后,添加上"DLL_1.lib",注意用空格与前面的lib隔开。然后单击OK按钮。

    6.然后编译、链接、运行试试?

哈哈~这个“253”意味着什么?

 

当然,同样的,关于DLL中变量和类的调用,我想应该是大同小异吧。

 

 

 

二、对于,仅有.dll文件的情况

实际上,我这次遇到的问题就是属于这种类型的,查的我好苦啊,现在终于解决了。 :)


当然,.dll文件在被提供时,应该也同时提供了一个说明文档,文档中应该已经给出了你可以调用的函数的功能及函数原型。如果他没有提供函数原型,那还需要一些手段来获得它,有关获取函数原型的方法,本文不做讨论。

 

这里首先给出我拿到的dll文件及其中的可被调用的函数原型:

kingvewcliend.dll(这个是DLL文件的文件名)中可被调用的函数有:

1、int ReadItemNo();
返回值:
返回组态王OPC中列出的项目总数

2、int StartCliend(char* node);
入口参数:
node为机器节点名称
返回值:
返回建立连接错误码
=========================================

  (一)接下来,是实现调用kingvewcliend.dll文件中的int ReadItemNo();函数的方法:

和上面讲的(一、(二)2.~3.)相同,先建立好控制台工程和cpp文件,然后输入下面的代码:

#include "stdio.h"
#include "windows.h"

void main()
{

 int a;
 HINSTANCE dll123;
 dll123 = LoadLibrary("kingvewcliend.dll");
 if (NULL == dll123)
  printf("cant't find dll");
 FARPROC msg1;
 msg1 = GetProcAddress(dll123, "ReadItemNo");
 if (NULL == msg1)
  printf("cant't frind function");
 else
  a = msg1();
 printf("%d/n",a);

}

在编译、链接、运行之前,一定要记着先把kingvewcliend.dll文件拷贝到工程文件夹内。

 

  (二)接下来,是实现调用kingvewcliend.dll文件中的int StartCliend(char* node);
函数的方法:

与上面int ReadItemNo();函数不同的是,int StartCliend(char* node);函数带了参数,怎么办呢?研究下下面的代码,你就明白了! :)

#include "stdio.h"
#include "windows.h"

void main()
{

 int a;

 char b = 1;
 typedef   int   (CALLBACK   *myfun1)(char*);
 HINSTANCE dll123;
 dll123 = LoadLibrary("kingvewcliend.dll");
 if (NULL == dll123)
  printf("cant't find dll");
 myfun1 msg1;
 msg1 = (myfun1)GetProcAddress(dll123, "StartCliend");
 if (NULL == msg1)
  printf("cant't find function");
 else
  a = msg1(&b);
 printf("%d/n",a);
}


推荐阅读
  • 本文档旨在提供C语言的基础知识概述,涵盖常量、变量、数据类型、控制结构及函数定义等内容。特别强调了常量的不同类型及其在程序中的应用,以及如何正确声明和使用函数。 ... [详细]
  • 本文详细介绍了在Luat OS中如何实现C与Lua的混合编程,包括在C环境中运行Lua脚本、封装可被Lua调用的C语言库,以及C与Lua之间的数据交互方法。 ... [详细]
  • C基本语法C程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。现在让我们简要地看一下什么是类、对象,方法、即时变量。对象-对象具有状态和行为 ... [详细]
  • 本文主要解决了在编译CM10.2时出现的关于Samsung Exynos 4 HDMI HAL库中SecHdmiV4L2Utils.cpp文件的编译错误。 ... [详细]
  • 本文探讨了 Boost 库中的 Program Options 组件,这是一个强大的工具,用于解析命令行参数和配置文件。文章介绍了如何正确设置和使用该组件,包括处理复杂选项和负数值的方法。 ... [详细]
  • 深入解析C++ Atomic编程中的内存顺序
    在多线程环境中,为了防止多个线程同时修改同一数据导致的竞争条件,通常会使用内核级同步对象,如事件、互斥锁和信号量等。然而,这些方法往往伴随着高昂的上下文切换成本。本文将探讨如何利用C++11中的原子操作和内存顺序来优化多线程编程,减少不必要的开销。 ... [详细]
  • 基于51单片机的多项目设计实现与优化
    本文探讨了基于51单片机的多个项目的设计与实现,包括PID控制算法的开关电源设计、八音电子琴仿真设计、智能抽奖系统控制设计及停车场车位管理系统设计。每个项目均采用先进的控制技术和算法,旨在提升系统的效率、稳定性和用户体验。 ... [详细]
  • 本文探讨了如何在 Spring MVC 框架下,通过自定义注解和拦截器机制来实现细粒度的权限管理功能。 ... [详细]
  • 多用户密码验证与加密登录系统
    本文介绍了一种基于多用户密码文件的加密登录方法,通过读取用户密码文件并使用简单的加密算法实现安全登录。文中详细描述了程序的设计思路及其实现过程。 ... [详细]
  • 基于Flutter实现风车加载组件的制作_Android
    Flutter官方提供了诸如 CircularProgressIndicator和 LinearProgressIndicator两种常见的加载指示组件,但是说实话,实在太普通,所 ... [详细]
  • 题目描述墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令ÿ ... [详细]
  • 题目描述:给定 n 把雨伞和 m 个人,t 分钟后开始下雨。求在每个人只能使用一把雨伞的情况下,最多有多少人可以拿到雨伞。 ... [详细]
  • 基于OpenCV的小型图像检索系统开发指南
    本文详细介绍了如何利用OpenCV构建一个高效的小型图像检索系统,涵盖从图像特征提取、视觉词汇表构建到图像数据库创建及在线检索的全过程。 ... [详细]
  • 2022年4月15日的算法练习题,包括最长公共子序列和线段树的应用。 ... [详细]
  • 本文深入探讨了领域驱动设计(DDD)中的聚合概念及其在事件溯源架构中的应用。聚合是一组紧密相关的类,这些类作为一个整体运作,形成一个有明确边界的组织。只有通过聚合根才能与聚合内的对象进行交互。 ... [详细]
author-avatar
立案whan_597
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有