dll 文件可以导入变量,函数,和C++类,但是导入变量会使执行程序与dll紧耦合,而C++类导入则需要两个文件的开发商所用的编译器相兼容,所以做好只导入函数;

创建dll : 
头文件:
#ifdef               MYLIBAPI                    //在dll源文件中必须定义这个宏为导出宏
#else                    //因为执行文件中必然没有定义这个宏所以
#define MYLIBAPI   __declspec(dllimport) //在执行文件中必定为导入宏
#endif
MYLIBAPI int g_nResult;                        //导入变量
MYLIBAPI int Add(int nLeft, int nRight);  //导入函数

源文件:
#include <windows.h>
#define MYLIBAPI   __declspec(dllexport)    //屏蔽掉头文件的导入宏为导出宏
#include "MyLib.h"
int g_nResult;
int Add(int nLeft, int nRight) {g_nResult = nLeft + nRight;   return(g_nResult);  }

隐式链接:
在mfc中调用win32 dll 的步骤:   (导出函数 /一般不导出c++类:可以只导出部分public函数)
1: 不要用extern "C",单独用_declspec (dllexport) ..... 生成dll 及 lib 文件;
2: 将lib 文件复制到当前程序目录,且将链接器的   输入->付加依赖项 中写入库文件;
3: 复制dll文件到debug 目录(必须的);
4:在调用函数时, 采用先声明外部函数 在使用;
 4.1: 用extern 来声明函数; 
 4.2: 用_declspec(dllimport) 来声明导入的函数 ;  (采用后者效率通常会更高)
对于带头文件的导入方式:
1: 其中第二三步不变, 采用文上的定义方式;
2:将头文件装置程序目录,并在原来声明外部函数的地方 #include<文件.h>,而不需要在显示声明函数原型了;

其中的 extern "C" 的作用是告诉c++编译器 不要改动所要导出的类型的名称,以防在别的模块中无法访问; (当在写c和c++的混合代码的时候,如果不加则会导致严重的链接问题)
当你用C++编译器写的dll,再用c语言的编译器来导入就会出错,而还是用同一种编译器便宜的话则不会出错;
可以通过dumpbin.exe 来查看所谓导出或者需要导入的dll 的信息;(exports /imports)
名字改编: 为了支持重载,按照自己的一套规则来改变函数的名字
这就导致了,要就要在客户端,和服务端同时用extern "C" 来用相同的规则来寻找同一个函数名;(要不就不要加)(用这个特性的话就不可以导出类函数;)

显示链接:(动态加载一个动态链接库) 这时候即使采用不同的调用约定(当然访问时,约定也要相同),其函数名也没有改变;
且不会dumpbin出需要动态加载的文件;   
1. 包含一个 .def文件  :文件中含有  EXPORTS    functionname  (这样就会只导出一个不会变的函数名称) 如果不用.def文件的话,可以在加载的时候,显示的使用变化后的函数名
将次dll文件的项目属性的   输入->模块定义文件-> 为 name.def                    就可以生成相应的.lib 文件了
(1)或者是                #pragma comment(linker, "/export:MyFunc=_MyFunc@8")
2.HMODULE LoadLibrary("dll or exe name ");           导入模块                                       这里返回的HMODULE句柄就相当于HINSTANCE,其实是dll文件加载后所在的虚拟内存地址
3.FARPROC GetProAddress();   获得函数入口地址
例如: typedef  int (* addproc)(int a ,int b);
addproc Add=(addproc)GetProcAddress(hmoudle,"add");                     或者使第二个函数为 MAKEINTERESOURCE(序号);
Add(10,10);
FreeLibrary(hmoudle);    卸载动态链接库
注: 在非vc情况下调用一个c++(非改名的c++或者是C)的dll 通常会出现的问题:是不是标准调用,如果是的话则函数名即使指定extern也会改变
原因:由于:ms 的c编译器即使在你没有使用c++代码的时候也会改变c 函数的名字, 只要在你调用函数的时候使用了WINAPI 的_stdcall(绝大多数的情况), 这时候编译器会产生一个有下划线起始的,以@+参数所占有的字节数 结尾的函数; 而ms的编译器可以正确翻译出相应的名字;
在使用其它非ms编译器来调用可用dll的时候,必须要使用以下两种方法:(指示其不要将函数改名)
    
DllMain() dll 文件的入口函数 (是可选的)   可以为自己的函数提供一个本dll文件的句柄来供dll 函数来使用;

如果在dll文件中分配内存的话,那么一定要提供相应的释放函数在dll中释放内存,即一个模块提供了分配内存的函数,那么它就同时也要提供释放内存的函数.

Win32 的dll导入的更多相关文章

  1. Win32中 DLL、Lib 库的创建机器使用

    Windows 下 的静态库和动态库 一.静态函数库(Lib) 1. 静态函数库的制作(C/C++) —— 打开新建项目,然后选中Win32项目,接着在创建项目中选择 Lib,再接着将函数.实现功能的 ...

  2. DLL学习笔记一(DLL导入导出)

    创建DLL: 先声明导出函数:使用__declspec(dllexport) #include"DLLSample.h" #ifndef _DLL_SAMPLE_H #define ...

  3. dll导入导出资源文件查看工具 InspectExe

    InspectExe lets you explore and diagnose problems with Win32 applications. It is integrated directly ...

  4. MinGW dll导入导出类

    dll不仅可以导入导出函数,还可以导入导出类.这篇文章就来介绍如何将类导入dll中并导出. 首先我们建立一个名为dll.cpp的文件(又是这种破名字),里面写上: #include <iostr ...

  5. dll导入导出宏定义,出现“不允许 dllimport 函数 的定义”的问题分析

    建立dll项目后,在头文件中,定义API宏 #ifndef API_S_H #define API_S_H ...... #ifndef DLL_S_20160424 #define API _dec ...

  6. Golang下通过syscall调用win32的dll(calling Windows DLLs from Go )

    很多同学比如我虽然很喜欢golang,但是还是需要调用很多遗留项目或者其他优秀的开源项目,这时怎么办呢?我们想到的方法是用package里的syscall结合cgo 注意此处有坑: 在我调试时显示no ...

  7. C#语言-NPOI.dll导入Excel功能的实现

    前言:刚工作那会,公司有一套完善的MVC框架体系,每当有导入EXCEL功能要实现的时候,都会借用框架里自带的导入方法,一般三下五除二就完成了,快是快,可总是稀里糊涂的,心里很没有底.前几天,在另一个原 ...

  8. Cypress USB3014 C++DLL 导入问题

    VS2017编译cpp工程出现问题 硬件型号:芯片版本 Cypress FX3 USB3014(和芯片无关)) 重现步骤: 1.解压 FX3_SDK_Windows_v1.3.3.exe 2.VS20 ...

  9. Unity基础-外部导入C# Dll(汇编集)

    外部导入C# Dll(汇编集) 使用创建一个dll工程 添加依赖的dll 导入Unity中,放入Assets的任意文件夹中 使用代码生成的dll汇编集只要"use dll的名字"引 ...

随机推荐

  1. LXPanel自定义添加应用程序到快速启动栏

    LXPanel是Linux下LXDE项目的一个桌面面板软件.我一开始接触的时候,对于自己自定义的程序到快速启动栏绕了很多弯路,这里记录下,防止以后自己忘了.还有一点就是很多时候,panel下的应用程序 ...

  2. javascript mvc 简单例子

    <!DOCTYPE html> <html> <head> </head> <body> <input type="text ...

  3. Python新手学习基础之数据结构-序列1

    序列概念 序列,顾名思义就是有顺序的列,在Python里序列类型的数据结构包括字符串,列表和元组.既然都是序列类型,说明他们有很多共通点,他们的每一个元素都可以通过指定的偏移量方式(索引操作)来获得, ...

  4. HDU 2955(01背包问题)

    M - 01背包 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   Descript ...

  5. iOS项目管理:目录结构和开发流程

    iOS项目管理:目录结构和开发流程     最近正在做一个大版本的更新,现在在重构中.... 发现很多人在一个项目的开始不知道开发流程是什么,也不是非常清晰的知道一个项目该有目录结构.如果项目小或者是 ...

  6. c语言实现一个链表

    一.基础研究 我们在这里要理解和实现一种最基本的数据结构:链表.首先看看实现的程序代码: List .h: 事实上我们观察list.h发现前面一部分是数据结构的定义和函数的声明,后面一部分是函数的实现 ...

  7. Oulipo

    poj3461:http://poj.org/problem?id=3461 题意:求一个串在另一个串中出现的次数. 题解:直接套用KMP即可,在统计的时候做一下修改.找到之后不是直接返回,而是移动i ...

  8. Qt自定义事件的实现(军队真正干活,但要增加监军,大平台通知事件,事件内容自定义)

    初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢?看了篇文章,说先要子类化QEvent,然后定义自己的QEvent::Type,然后重写QWidget::event ...

  9. SDUT2484 算术表达式的转换(表达式树)

    题目链接. 分析: 转换成表达式树,然后先序.中序.后序遍历. AC代码如下: #include <stdio.h> #include <string.h> #define m ...

  10. 【转】在linux内核中读写文件 -- 不错

    原文网址:http://blog.csdn.net/tommy_wxie/article/details/8194276 1. 序曲 在用户态,读写文件可以通过read和write这两个系统调用来完成 ...