dll的创建和使用的整理【部分转载】

如何用MFC生成DLL

1.   新建—项目—MFC DLL

    使用共享 MFC DLL 的规则 

2.  修改OneDLL.cpp文件和OneDLL. def文件

   OneDLL.cpp文件是DLL的主要的源代码文件, 

   OneDLL.def文件包含了DLL提供了一些参数,如DLL的名称和属性和从DLL中输出的函数。

3. 修改OneDLL.cpp文件

#include "stdafx.h"

#include "OneDLL.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

 

int Message1(void);              //需要添加的地方

int Message2(void);              //需要添加的地方

 

BEGIN_MESSAGE_MAP(COneDLLApp, CWinApp)

END_MESSAGE_MAP()

// COneDLLApp 构造

COneDLLApp::COneDLLApp()

{

// TODO: 在此处添加构造代码,

// 将所有重要的初始化放置在 InitInstance 

}

// 唯一的一个 COneDLLApp 对象

COneDLLApp theApp;

// COneDLLApp 初始化

BOOL COneDLLApp::InitInstance()

{

CWinApp::InitInstance();

return TRUE;

}

 

int Message1(void)      //需要添加的地方

   MessageBox(NULL,_T("This is the first example of testing DLL."),NULL,MB_OKCANCEL); 

return 1; 

int Message21(void)     //需要添加的地方

   MessageBox(NULL,_T("This is the second example of testing DLL."),NULL,MB_OKCANCEL); 

return 1; 

记得设为为多字节而非unicode编码。

4.修改.def文件:

OneDLL.def : 声明 DLL 的模块参数。

 

LIBRARY "OneDLL"                //需要修改的地方

EXPORTS Message1

EXPORTS Message2 

5点击生成——生成解决方案

    可以生成相关的(可以在OneDLL\Debug进行查看)

dll文件 -----动态链接用(推荐使用)

    lib文件 ---- 静态链接用

ilk文件 ---- 静态链接用

 

 

 

 推荐阅读:

MFC调用DLL文件:动态调用(以一个例子为说明):

1.新建一个基于MFC框架的单文档工程,并在TestDLLView.cpp文件开始处添加

HINSTANCE handlerDLL=NULL;    //需要添加

typedef int(* MESSAGE)(void); 

MESSAGE Message;

 

2.然后在菜单中添加DLL主菜单、子菜单,如下图所示,以及View类下的菜单响应函数。

子菜单ID分别为IDDLLLOADIDDLLTEST

 

void CTestDLLView::OnDllLoaddll()

{

handlerDll=LoadLibrary(_T("OneDll.DLL"));

if (handlerDll!=NULL

{

     MessageBox(_T("Has been loaded."));                   Message1=(MESSAGE)GetProcAddress(handlerDll,_T("Message"));     Message2=(MESSAGE)GetProcAddress(handlerDll,_T("MessageTwo"));

 if (Message1!=NULL)

  {

Message1();

      Message2();

}

else

{

      MessageBox(_T("Can not been  loaded.")); 

}

FreeLibrary(handlerDll);

return;

// TODO: 在此加入您的命令處理常式程式碼

}

 

 

3. 接着,进行生成——生成解决方案,提示如下错误:

通过查看是 Message=(MESSAGE)GetProcAddress(handlerDLL,_T("Message"));引起的,解决办法是:右击视图栏中的工程名——属性——项目默认值——字符集——使用多字节字符集(原来是使用Unicode字符集)——确定,重新生成解决方案,错误消失。

 

4.将DLL文件放入DEBUG

 OneDll.DLL放入DEBUG

5.执行

 

 

 

如果提示Cannot Load the OneDLL.DLL说明设置的调用DLL的路径有问题;

 

 

 

MFC调用DLL的方法(加深印象):

 HINSTANCE  hInst = LoadLibrary(L"User32.DLL"); // 加载DLL
  if(hInst)                              // 加载成功
     {
        定义待访问函数原型 
        typedef  BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD); 
        MYFUNC fun = NULL; 
        fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");// 获取函数地址
        if(fun)                               // 成功
           {
             fun(hWnd, RGB(0, 0, 0), 255, 2 | 1);
             }
         FreeLibrary(hInst); //释放 DLL
       } 

1,隐式连接.将制作好的.dll.lib.h三个文件COPY到你要用的工程下,然后在工程中加入

   #pragma comment(lib,"somedll.lib")

   //somedll.lib  其中somedll是你要调用的库的名字..然后直接调用你的funa就可以了

     这是告诉编译器在编译形成的.obj文件,使得 链接器在链接库的时候要去找        

     wsock32.lib这个库,不要先去找别的库。

2.显式连接

    typedef          int         (* lpFuna)                       (int,int);

  int main(int argc, char* argv[])

          {

             HINSTANCE hDll; 

             lpFuna Funa;

             hDll = LoadLibrary("a.dll");

             if (hDll != NULL)

                {

                   // Funa = (lpFuna)GetProcAddress(hDll,"Funa"); 

                      Funa = (lpFuna)GetProcAddress(hDll,MAKEINTRESOURCE(2));

                                             //MAKEINTRESOURCE直接使用导出文件中的序号

     if(Funa!=NULL)

        {

             int result =  Funa(2,3);    

              printf("\ncall add in dll:%d",result);

         } 

      FreeLibrary(hDll);

 }

 

 

VB中调用DLL的:

步骤1:

例如我们有my.dll这个东西

将其放入system32中,

然后注册一下:   regsve32   my.dll  

步骤2:

专案----设定引用项目---找到my.dll这个东西

 

  dim AAA as asdfg           // asdfg是类模块的名称'

  Private Sub Form_Load() 

     dim x

     Set AAA = New asdfg 

      x = AAA.zxc(参数1,参数2)            '参数1,2自己写

  End Sub 

步骤2(或者):

 

Option Explicit

Declare Function B_8134_initial Lib "8134A.DLL" Alias "_8134_initial" (existCards As Integer) As Integer

Declare Function B_8134_close Lib "8134A.DLL" Alias "_8134_close" () As Integer

Declare Function B_8134_int_control Lib "8134A.DLL" Alias "_8134_int_control" (ByVal CardNo As Integer, ByVal intFlag As Integer) As Integer

Declare Function B_8134_int_disable Lib "8134A.DLL" Alias "_8134_int_disable" (ByVal CardNo As Integer) As Integer

 

b = B_8134_initial(a)

 

 

 

 

如何在VB中调用VC编写的DLL 

 VB和VC共同编程有3种方式:

                VC生成DLL,在VB中调用DLL

                VC生成ActiveX控件(.ocx),在 VB中插入;

                VC中生成ActiveX  Automation服务器,在VB中调用。

第一种方法对VC编程者的要求最低,但要求你的伙伴进行配合,我推荐这种方法。  

 

VC++中生成Win32  DLL工程

 在这个工程中添加几个函数供VB用户调用。

一个DLL中的函数要想被VB调用,必须满足两个条件:

                             一是调用方式为stdcall

                             二是必 须是export的

要做到第一条,只须在函数声明前加上__stdcall关键字。如:  

short __stdcall sample(short nLen, short *buffer)  

要做到第二条,需要在*.def文件中加上如下的几行:  

EXPORTS  

sample @1

这 里的sample是你要在VB中调用的函数名,@1表示该函数在DLL中的编号,每个函数都不一样。注意这里的函数名是区分大小写的。

 

 

就象上面的例 子,nLen是数组大小,buffer是数组地址,有了这两条,你可以象使用VC的数组一样进行处理了。

 

 

VB调用DLL的方法

(Declare Function B_8134_initial  Lib "8134A.DLL" Alias "_8134_initial" (existCards As Integer) As Integer)

 VB调用DLL的方法和调用Windows API的方法是一样的,一般在VB的书中有介绍。对于上面一个例子,先要声明VC函数:  

Declare  Function  sample   Lib "mydll.dll" (ByVal  nLen As Integer, buffer As Integer)  As Integer  

这里mydll.dll是你的dll的名字。你可能已经注意到了两个参数的声明有所不同,第一个参数加上了ByVal。规则是这样的:如果在VC中某个参数声明为指针和数组,就不加ByVal,否则都要加上ByVal。

在VB中调用这个函数采用这样的语法:  

sample (10, a(0))  

这里的a()数组是用来存放数据的,10为数组长度,这里的第二个参数不能是a(),而必须是要传递的数据中的第一个。这是VB编程的关键。  

 

 

下面在说几个可能遇到的问题

 1. VB报告找不到需要的函数,这通常是因为在VC中*.def文件没设置。

 2. VB告诉不能进行转换,这可能是在VC中没有加上 __stdcall关键字,也可能是VB和VC的参数类型不一致,注意在VC中int是4个字节(相当于VB的Long),而VB的Integer只有     2 个字节。必须保证VB和VC的参数个数相同,所占字节数也一致。

 3.在VC环境下创建的DLL,在VC里运行的好好的,可在VB应用程序中调用时却老是出    现"调用约定错误"、"找不到入口点"之类的错误。这主要是由以下疏漏造成的。 

  首先,要注意DLL中的函数和VB中的函数声明在名称、返回类型、参数类型、参数个数等方面必须完全相同,尤其要注意大小写的问题。 

  其次,在DLL的.def文件中必须加上入口函数。 

  最后,在函数定义前必须加上extern "c",_stdcall关键字。 

  具体格式可参看应用实例。  

  

  

 

 

 数组参数在DLL中的传递 

  由于DLL经常用来进行一些底层的运算操作,因此应用程序常需要传递大量的数据给DLL。在C++中,指针是进行数组操作的最佳选择,但VB中没有指针的概念。这通常可用两种方法来解决。 

  其一,在VB中声明DLL时,用byref来代替byval,即可将数组指针传递给DLL。 

  另外,将数组声明为变体型(variant),即可直接将数组传递给DLL。 

  

  

Vc中创建Dll 

一、DLL的创建 
创建项目: Win32->Win32项目,名称:MyDLL


选择DLL (D) ->完成.

1、新建头文件testdll.h
testdll.h代码如下:

#ifndef TestDll_H_
#define TestDll_H_
#ifdef MYLIBDLL
#define MYLIBDLL extern "C" _declspec(dllimport) 
#else
#define MYLIBDLL extern "C" _declspec(dllexport) 
#endif
MYLIBDLL int Add(int plus1, int plus2);
//You can also write like this:
//extern "C" {
//_declspec(dllexport) int Add(int plus1, int plus2);
//};
#endif



2、新建源文件testdll.cpp
testdll.cpp代码如下:

#include "stdafx.h"
#include "testdll.h"
#include <iostream>
using namespace std;
int Add(int plus1, int plus2)
{
int add_result = plus1 + plus2;
return add_result;
}




3、新建模块定义文件mydll.def
mydll.def代码如下:

LIBRARY "MyDLL"
EXPORTS
Add @1



4、vs2010自动创建dllmain.cpp文件,它定义了DLL 应用程序的入口点。

dllmain.cpp代码如下:
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE 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;
}

最后,编译生成MyDLL.dll文件和MyDLL.lib文件。



1>------ 已启动生成: 项目: MyDLL, 配置: Debug Win32 ------

1>  dllmain.cpp

========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========

 

1>------ 已启动生成: 项目: MyDLL, 配置: Debug Win32 ------

1>  stdafx.cpp

1>  testdll.cpp

1>  MyDLL.cpp

1>  正在生成代码...

1>     正在创建库 D:\Visual C++\工程\Libaray\MyDLL\Debug\MyDLL.lib 和对象 D:\Visual C++\工程\Libaray\MyDLL\Debug






VB中的调用声明: 

 Public Declare Function Fourier Lib "SigPro" (ByRef Sample() As Long,  ByVal NumSam As Integer, ByVal OvertoneOrder As Integer, ByVal SinOrCos  As Boolean) As Double  

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值