1、lib.h

 1 #ifndef LIB_H
2 #define LIB_H
3
4 #include <windows.h>
5 #include <iostream>
6
7 using namespace std;
8
9 extern "C" int __declspec(dllexport)add(int,int);
10 extern "C" int __declspec(dllexport)sub(int,int);
11
12 //int add(int,int);
13 //int sub(int,int);
14
15 #endif

lib.h

2、lib.cpp

 #include "lib.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;
}*/ int add(int x, int y)
{
return x + y;
}
int sub(int x, int y)
{
return x - y;
}

lib.cpp

3、main.cpp

 #include "lib.h"

 int main(){
//DLL句柄声明
//HINSTANCE hDll;
HMODULE hDll; //加载DLL,返回句柄:
//HMODULE WINAPI LoadLibrary( _In_ LPCTSTR lpFileName);
//hDll=LoadLibrary(_T("lib.dll"));
hDll=LoadLibrary(TEXT("lib.dll"));//hDll=LoadLibrary("lib.dll");
if(hDll==NULL)
cout << "dll加载失败!" << endl;
cout << "dll加载成功!" << endl;
cout << "dll句柄:" << hDll <<endl; //定义与add函数接受参数类型和返回值均相同的函数指针类型
typedef int(*lpAddFun)(int,int);
typedef int(*lpSubFun)(int,int); lpAddFun addFun;
lpSubFun subFun; //
//GetProcAddress函数原型:
//FARPROC GetProcAddress(
//HMODULE hModule, // DLL模块句柄
//LPCSTR lpProcName); // 函数名
LPCSTR add="add";
LPCSTR sub="sub";
int *numFun; if(hDll!=NULL){
addFun=(lpAddFun)GetProcAddress(hDll,add);
cout << "addFun :" << addFun << endl;
subFun=(lpSubFun)GetProcAddress(hDll,sub);
cout << "subFun :" << subFun << endl;
numFun=(int *)GetProcAddress(hDll,"num");
cout << "numFun1:" << numFun << endl;
if(addFun!=NULL){
int result=addFun(,);
cout << "3+2=" << result << endl;
}
if(subFun!=NULL){
int result=subFun(,);
cout << "3-2=" << result << endl;
}
if(numFun!=NULL){
cout << "numFun2:"<< numFun <<endl;//没有num函数,就返回NULL
}
FreeLibrary(hDll);//释放DLL
cout << "dll卸载成功!";
}
return ;
}

main.cpp

4、编译lib.cpp为dll

  cl /LD lib.cpp

  生成lib.dll,同时还有lib.exp、lib.lib

5、编译main.cpp为main.exe

  cl main.cpp

6、DLL中导出函数的声明有两种方式:

  6.1、一种方式为例子中给出的:

    在函数声明中加上__declspec(dllexport)
  6.2、另外一种方式是采用模块定义(.def) 文件声明

    .def文件为链接器,提供了有关被链接程序的导出、属性及其他方面的信息。
    代码中lib.cpp中注释部分演示了怎样同.def文件,

    将函数add声明为DLL导出 函数(需在dllTest工程中添加lib.def文件)

       lib.def : 导出DLL函数
      LIBRARY libdll

      EXPORTS
      add @ 1
      .def文件的规则为:
        (1)LIBRARY语句说明.def文件相应的DLL;
        (2)EXPORTS语句后列出要导出函数的名称。可以在.def文件中
       的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调
       用时,这个序号将发挥其作用);
        (3).def 文件中的注释由每个注释行开始处的分号 (;) 指定,
       且注释不能与语句共享一行。
    由此可以看出,例子中lib.def文件的含义为生成名为“libdll”
    的动态链接库,导出其中的add函数,并指定add函数的序号为1。

7、当使用第一种声明导出函数函数时,将"C"改为C++,

则main.cpp不能成功调用到lib.dll中的各个函数。

c/c++调用dll的更多相关文章

  1. Windows平台Go调用DLL的坑

    最近的项目中,使用了GO来开发一些服务中转程序.业务比较简单,但是有一些业务需要复用原有C++开发的代码.而在WINDOWS,用CGO方式来集成C/C++代码并不是太方便.所以用DLL把C++的代码封 ...

  2. Java 调用 C++ (Java 调用 dll)康哥手把手教你

    摘要: 本文原创,转载请注明地址 http://www.cnblogs.com/baokang/p/4979243.html 因为要做点图形处理的项目,需要在Java中调用dll库,所以开发的第一步是 ...

  3. 【转】C#调用DLL

    C#中如何调用动态链接库DLL(转)     每种编程语言调用DLL的方法都不尽相同,在此只对用C#调用DLL的方法进行介绍.首先,您需要了解什么是托管,什么是非托管.一般可以认为:非托管代码主要是基 ...

  4. C#程序实现动态调用DLL的研究(转)

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  5. 外壳exe通过反射调用dll时

    外壳exe通过反射调用dll时,dll是 4.0的框架,外壳exe也需要编译成4.0的框架,如果dll本身有调用32位的dll,那么外壳exe也需要编译成32位. 调试时报的那个错,直接继续运行,不影 ...

  6. C++ exe调用dll文件

    生成dll程序 extern "C"_declspec(dllexport) void maopao(int *p,int count);void maopao(int *p,in ...

  7. 卸载AppDomain动态调用DLL异步线程执行失败

    应用场景 动态调用DLL中的类,执行类的方法实现业务插件功能 使用Assembly 来实现 但是会出现逻辑线程数异常的问题 使用AppDomain 实现动态调用,并卸载. 发现问题某个插件中开启异步线 ...

  8. C++ 生成 dll 和调用 dll 的方法实例(转)

    1)生成dll 建立两个文件 xxx.h , xxx.cpp xxx.h内容如下: #ifdef BUILD_XXX_DLL#define EXPORT __declspec(dllexport)#e ...

  9. 在VC中创建并调用DLL

    转自:http://express.ruanko.com/ruanko-express_45/technologyexchange6.html 一.DLL简介 1.什么是DLL? 动态链接库英文为DL ...

  10. [转]如何在Java中调用DLL方法

    转载地址:http://developer.51cto.com/art/200906/129773.htm Java语言本身具有跨平台性,如果通过Java调用DLL的技术方便易用,使用Java开发前台 ...

随机推荐

  1. 如何用Project2010制作WBS

    如何用Project2010制作WBS: http://www.projectup.net/blog/index.php?option=com_content&view=article& ...

  2. 【BZOJ2525】[Poi2011]Dynamite 二分+树形DP

    [BZOJ2525][Poi2011]Dynamite Description Byteotian Cave的结构是一棵N个节点的树,其中某些点上面已经安置了炸.药,现在需要点燃M个点上的引线引爆所有 ...

  3. C 语言开发初涉-01 简单学习

    尝试用C语言写windows程序: 简单的计算器 1.0版,仅用来熟悉C 开发windows的一些语法和语句用法 #include "stdafx.h" #include < ...

  4. poj2826 An Easy Problem?!【计算几何】

    含[三点坐标计算面积].[判断两线段是否有交点].[求线段交点]模板   An Easy Problem?! Time Limit: 1000MS   Memory Limit: 65536K Tot ...

  5. 巨蟒python全栈开发-第11阶段 devops-git入门1

    大纲 1.git命令初识 2.git reset与diff 3.git区域总结 4.git 远程仓库 5.git stash 1.git命令初识 2.git reset与diff 3.git区域总结 ...

  6. Storm 在ZK 上的目录图

    这是Zk 的可视化工具 看到的Storm 目录结构 ,这时候没有提交任何的任务给这个集群, 其实这时候我只是启动了 nimbus 还没有启动Supervisors  ,所有你 看懂的Superviso ...

  7. python - 用户交互/数据类型/格式化输出/运算符/流程控制单双多分支

    python:用户交互: 等用户输入,做反应: username=input("username:")password=input("password:")pr ...

  8. 剑指Offer——链表中环的入口结点

    题目描述: 一个链表中包含环,请找出该链表的环的入口结点. 分析: 设置两个指针p1,p2, 两个指针都从链表的头部开始走,不过p1每次走一步,p2每次走两步. 直到相遇的时候,p2走的长度是p1的两 ...

  9. java基础04 Scanner的使用

    import java.util.Scanner; /** * 所有在java.lang包下面的所有类 不需要显示的引入包! * java.util.Scanner : 想获取用户的输入 必须引入相关 ...

  10. Fibonacci----poj3070(矩阵快速幂, 模板)

    题目链接:http://poj.org/problem?id=3070 . 就是斐波那契的另一种表示方法是矩阵的幂: 所以是矩阵快速幂:矩阵快速幂学习 #include <cstdio> ...