您的位置:首页 > 其它

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

2015-11-01 19:10 1046 查看
如何用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分别为IDDLLLOAD和IDDLLTEST

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: