如何用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