VS2010 开发 VB6.0 activeX控件 dll
项目源码
https://download.csdn.net/download/csdn_z_s/10427764
开发环境
操作系统: win7 64位 旗舰版
Java语言开发环境: Eclipse3.7(jdk1.6u45)
C/C++语言开发环境: cn_visual_studio_2010_ultimate_x86
VB语言开发环境: VB6.0
前言
我们的项目主要以java为编写语言, 涉及到调用本地设备的底层模块使用的C/C++语言, java和C/C++之间利用JNI技术进行调用. 底层模块在和本地设备进行对接的方式之一是集成DLL(动态链接库)的形式.
前段时间项目中需要集成第三方厂家(Y厂)的DLL(YC.DLL), Y厂的DLL是使用VB编写的, 编译环境是VB6.0. 拿到DLL后, 先用Dependency Walker看了下内部的接口名称, 就四个:
DllCanUnloadNow
DllGetClassObject
DllRegisterServer
DllUnregisterServer
果然, 这就是传说中的activeX, 从网上的资料看, VB6.0编译出的dll均属于activeX控件.
至于DLL, OCX, activeX, COM组件概念上的区别, 网上都有很好的资料.
小插曲
刚拿到Y厂的YC.DLL后, 按照下一节的步骤, 在编译YC.DLL后, 编译器会提示”无法加载的动态库类型”, 而Y厂并没有相关的C/C++技术支持可以提供C/C++对他们的DLL的调用方式. 虽然自己之前也写过ocx控件, 将自己的ocx控件按照下一节的步骤, 编译一切正常. 但自己没有过在VB6.0编译器上通过VB语言进行开发的经验, 这让开发进度一再停滞.
后来偶然间在网页上查到一个在VS2010上引用VB6.0编译的dll的帖子, 截图如下:
按照图片所说的步骤, 我的vs2010竟然真的可以引用Y厂的dll.
关于vb6controls.reg可以参考:
REGEDIT
HKEY_CLASSES_ROOT\Licenses = Licensing: Copying the keys may be a violation of established copyrights.
// Masked Edit Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\BC96F860-9928-11cf-8AFA-00AA00C00905 = mmimfflflmqmlfffrlnmofhfkgrlmmfmqkqj
// Chart Control 6.0 (OLEDB) license key
HKEY_CLASSES_ROOT\Licenses\12B142A4-BD51-11d1-8C08-0000F8754DA1 = aadhgafabafajhchnbchehfambfbbachmfmb
// Common Dialog Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\4D553650-6ABE-11cf-8ADB-00AA00C00905 = gfjmrfkfifkmkfffrlmmgmhmnlulkmfmqkqj
// ADO Data Control 6.0 (OLEDB) license key
HKEY_CLASSES_ROOT\Licenses\C4145310-469C-11d1-B182-00A0C922E820 = konhqhioohihphkouimonhqhvnwiqhhhnjti
// Common Controls-3 6.0 license key
HKEY_CLASSES_ROOT\Licenses\38911DA0-E448-11D0-84A3-00DD01104159 = mcpckchcdchjcjcclidcgcgchdqdcjhcojpd
// Windows Common Controls-2 5.0 (SP2) license key
HKEY_CLASSES_ROOT\Licenses\9E799BF1-8817-11cf-958F-0020AFC28C3B = uqpqnqkjujkjjjjqwktjrjkjtkupsjnjtoun
// Windows Common Controls license key
HKEY_CLASSES_ROOT\Licenses\57CBF9E0-6AA7-11cf-8ADB-00AA00C00905 = aahakhchghkhfhaamghhbhbhkbpgfhahlfle
// Data Bound Grid Control 5.0(SP3) license key
HKEY_CLASSES_ROOT\Licenses\556C75F1-EFBC-11CF-B9F3-00A0247033C4 = xybiedobrqsprbijaegcbislrsiucfjdhisl
// Data Bound List Controls 6.0 license key
HKEY_CLASSES_ROOT\Licenses\096EFC40-6ABF-11cf-850C-08002B30345D = knsgigmnmngnmnigthmgpninrmumhgkgrlrk
// Internet Transfer Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\78E1BDD1-9941-11cf-9756-00AA00C00908 = yjrjvqkjlqqjnqkjvprqsjnjvkuknjpjtoun
// Multimedia Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\B1EFCCF0-6AC1-11cf-8ADB-00AA00C00905 = qqkjvqpqmqjjpqjjvpqqkqmqvkypoqjquoun
// Chart Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\7C35CA30-D112-11cf-8E72-00A0C90F26F8 = whmhmhohmhiorhkouimhihihwiwinhlosmsl
// Windows Common Controls-2 6.0 license key
HKEY_CLASSES_ROOT\Licenses\4F86BADF-9F77-11d1-B1B7-0000F8753F5D = iplpwpnippopupiivjrioppisjsjlpiiokuj
// Windows Common Controls 6.0 license key
HKEY_CLASSES_ROOT\Licenses\ED4B87C4-9F76-11d1-8BF7-0000F8754DA1 = knlggnmntgggrninthpgmnngrhqhnnjnslsh
// Comm Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\4250E830-6AC2-11cf-8ADB-00AA00C00905 = kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun
// DataGrid Control 6.0 (OLEDB) license key
HKEY_CLASSES_ROOT\Licenses\CDE57A55-8B86-11D0-b3C6-00A0C90AEA82 = ekpkhddkjkekpdjkqemkfkldoeoefkfdjfqe
// DataList Control 6.0 (OLEDB) license key
HKEY_CLASSES_ROOT\Licenses\A133F000-CCB0-11d0-A316-00AA00688B10 = cibbcimbpihbbbbbnhdbeidiocmcbbdbgdoc
// DBWin license key
HKEY_CLASSES_ROOT\Licenses\D015B071-D2ED-11d0-A31A-00AA00688B10 = gjdcfjpcmjicjcdcoihcechjlioiccechepd
// MSDBRPT license key
HKEY_CLASSES_ROOT\Licenses\9DF1A470-BA8E-11D0-849C-00A0C90DC8A9 = cchcqjejhcgcqcfjpdfcdjkckiqikchcojpd
// FlexGrid Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\72E67120-5959-11cf-91F6-C2863C385E30 = ibcbbbebqbdbciebmcobmbhifcmciibblgmf
// MAPI Controls 6.0 license key
HKEY_CLASSES_ROOT\Licenses\899B3E80-6AC6-11cf-8ADB-00AA00C00905 = wjsjjjlqmjpjrjjjvpqqkqmqukypoqjquoun
// MSRDO 2.0 license key
HKEY_CLASSES_ROOT\Licenses\B1692F60-23B0-11D0-8E95-00A0C90F26F8 = mjjjccncgjijrcfjpdfjfcejpdkdkcgjojpd
// RemoteData Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\43478d75-78e0-11cf-8e78-00a0d100038e = imshohohphlmnhimuinmphmmuiminhlmsmsl
// Windowless Controls 6.0 license key
HKEY_CLASSES_ROOT\Licenses\80E80EF0-DBBE-11D0-BCE2-00A0C90DCA10 = qijimitpmpnpxplpvjnikpkpqoxjmpkpoivj
// PictureClip Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\6FB38640-6AC7-11cf-8ADB-00AA00C00905 = gdjkokgdldikhdddpjkkekgknesjikdkoioh
// Rich TextBox Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\DC4D7920-6AC8-11cf-8ADB-00AA00C00905 = iokouhloohrojhhhtnooiokomiwnmohosmsl
// Sheridan Tab Control license key
HKEY_CLASSES_ROOT\Licenses\190B7910-992A-11cf-8AFA-00AA00C00905 = gclclcejjcmjdcccoikjlcecoioijjcjnhng
// SysInfo Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\E32E2733-1BC5-11d0-B8C3-00A0C90DCA10 = kmhfimlflmmfpffmsgfmhmimngtghmoflhsg
// Winsock Control 6.0 license key
HKEY_CLASSES_ROOT\Licenses\2c49f800-c2dd-11cf-9ad6-0080c7e7b78d = mlrljgrlhltlngjlthrligklpkrhllglqlrk
集成方式-#import
语法:
#import "dllPath" no_namespace
使用#import语句, 然后对项目进行重新编译, 编译器会在工程目录下生成两个文件:YC.tlh与YC.tli, 其中YC.tlh文件类似于C/C++的头文件, 里面有dll接口声明:
struct __declspec(uuid("578277c2-7735-4c61-a141-1df16558cd4d"))
/* LIBID */ __SmartCardLib;
struct __declspec(uuid("fa7ab805-ec44-4a84-b876-52da8a5fe3c3"))
/* dual interface */ _clsSmartCard;
struct /* coclass */ clsSmartCard;
struct __declspec(uuid("ff073a9e-e768-4024-b9cf-bcc05efd1329"))
/* dispinterface */ __clsSmartCard;
_COM_SMARTPTR_TYPEDEF(_clsSmartCard, __uuidof(_clsSmartCard));
_COM_SMARTPTR_TYPEDEF(__clsSmartCard, __uuidof(__clsSmartCard));
struct __declspec(uuid("fa7ab805-ec44-4a84-b876-52da8a5fe3c3"))
_clsSmartCard : IDispatch
{
};
struct __declspec(uuid("5c4d3831-f09d-471b-82a0-0e84240c8afc"))
clsSmartCard;
struct __declspec(uuid("ff073a9e-e768-4024-b9cf-bcc05efd1329"))
__clsSmartCard : IDispatch
{
// Methods:
};
这个文件告诉我们两个非常重要的信息:
一是, 通过” struct /* coclass */ clsSmartCard;”这行代码, 得知YC.DLL的
CLSID(5c4d3831-f09d-471b-82a0-0e84240c8afc ), CLSID可以认为是对接YC.DLL的入口.
二是, 通过_clsSmartCard : IDispatch 和__clsSmartCard : IDispatch 得知
_clsSmartCard 和 __clsSmartCard是DLL内部的接口声明, 通过接口声明, 我们可以知道这个动态库为我们提供了哪些功能.
import.h
#import "C:\\YC.dll" no_namespace
智能指针
#include <Windows.h>
#include "import.h"
#include <atlbase.h>
void main_CComPtr(){
if (!SUCCEEDED(CoInitialize(NULL)))
{
return;
}
CLSID clsid;
HRESULT hr = CLSIDFromString(L"{5c4d3831-f09d-471b-82a0-0e84240c8afc}", &clsid);
if (!SUCCEEDED(hr))
{
return;
}
// 创建CLSID的另一种方式
//CLSID clsid;
//clsid.Data1=0x5c4d3831;
//clsid.Data2=0xf09d;
//clsid.Data3=0x471b;
//clsid.Data4[0]=0x82;
//clsid.Data4[1]=0xa0;
//clsid.Data4[2]=0x0e;
//clsid.Data4[3]=0x84;
//clsid.Data4[4]=0x24;
//clsid.Data4[5]=0x0c;
//clsid.Data4[6]=0x8a;
//clsid.Data4[7]=0xfc;
CComPtr<_clsSmartCard> pGetRes;
pGetRes.CoCreateInstance(clsid);
printf("%d", pGetRes->Connect("gouqi"));
VARIANT cardNo;
VARIANT customNo;
VARIANT orderdate;
VARIANT orderAmount;
VARIANT orderNum;
VARIANT orderTotal;
VARIANT fgs;
VARIANT glz;
VARIANT cardStatus;
VARIANT factoryCode;
VARIANT cardPwd;
VARIANT cardType;
VARIANT chgPwd;
::VariantInit(&cardNo);
::VariantInit(&customNo);
::VariantInit(&orderdate);
::VariantInit(&orderAmount);
::VariantInit(&orderNum);
::VariantInit(&orderTotal);
::VariantInit(&fgs);
::VariantInit(&glz);
::VariantInit(&cardStatus);
::VariantInit(&factoryCode);
::VariantInit(&cardPwd);
::VariantInit(&cardType);
::VariantInit(&chgPwd);
pGetRes->readCard(&cardNo,
&customNo,
&orderdate,
&orderAmount,
&orderNum,
&orderTotal,
&fgs,
&glz,
&cardStatus,
&factoryCode,
&cardPwd,
&cardType,
&chgPwd );
pGetRes->Disconnect();
pGetRes.Release();
CoUninitialize();
}
CoGetClassObject
#include "import.h"
void mainCoGetClassObject(){
CoInitialize(NULL);
CLSID clsid;
HRESULT hr = CLSIDFromString(L"{5c4d3831-f09d-471b-82a0-0e84240c8afc}", &clsid);
if (!SUCCEEDED(hr))
{
return;
}
_clsSmartCard* ptr;
IClassFactory* p_classfactory;
hr=CoGetClassObject(clsid,CLSCTX_INPROC_SERVER,
NULL,IID_IClassFactory,
(LPVOID*)&p_classfactory);
p_classfactory->CreateInstance(NULL,__uuidof(_clsSmartCard),
(LPVOID*)&ptr);
printf("mainCoCreateInstance - > Connect=%d", ptr->Connect("gouqi"));
VARIANT cardNo;
VARIANT customNo;
VARIANT orderdate;
VARIANT orderAmount;
VARIANT orderNum;
VARIANT orderTotal;
VARIANT fgs;
VARIANT glz;
VARIANT cardStatus;
VARIANT factoryCode;
VARIANT cardPwd;
VARIANT cardType;
VARIANT chgPwd;
::VariantInit(&cardNo);
::VariantInit(&customNo);
::VariantInit(&orderdate);
::VariantInit(&orderAmount);
::VariantInit(&orderNum);
::VariantInit(&orderTotal);
::VariantInit(&fgs);
::VariantInit(&glz);
::VariantInit(&cardStatus);
::VariantInit(&factoryCode);
::VariantInit(&cardPwd);
::VariantInit(&cardType);
::VariantInit(&chgPwd);
ptr->readCard(&cardNo,
&customNo,
&orderdate,
&orderAmount,
&orderNum,
&orderTotal,
&fgs,
&glz,
&cardStatus,
&factoryCode,
&cardPwd,
&cardType,
&chgPwd );
ptr->Disconnect();
CoUninitialize();
}
C oCreateInstance
CoCreateInstance
#include "import.h"
void mainCoCreateInstance(){
CoInitialize(NULL);
CLSID clsid;
HRESULT hr = CLSIDFromString(L"{5c4d3831-f09d-471b-82a0-0e84240c8afc}", &clsid);
if (!SUCCEEDED(hr))
{
return;
}
_clsSmartCard *ptr;
hr=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
__uuidof(_clsSmartCard),(LPVOID*)&ptr);
printf("mainCoCreateInstance - > Connect=%d", ptr->Connect("gouqi"));
VARIANT cardNo;
VARIANT customNo;
VARIANT orderdate;
VARIANT orderAmount;
VARIANT orderNum;
VARIANT orderTotal;
VARIANT fgs;
VARIANT glz;
VARIANT cardStatus;
VARIANT factoryCode;
VARIANT cardPwd;
VARIANT cardType;
VARIANT chgPwd;
::VariantInit(&cardNo);
::VariantInit(&customNo);
::VariantInit(&orderdate);
::VariantInit(&orderAmount);
::VariantInit(&orderNum);
::VariantInit(&orderTotal);
::VariantInit(&fgs);
::VariantInit(&glz);
::VariantInit(&cardStatus);
::VariantInit(&factoryCode);
::VariantInit(&cardPwd);
::VariantInit(&cardType);
::VariantInit(&chgPwd);
ptr->readCard(&cardNo,
&customNo,
&orderdate,
&orderAmount,
&orderNum,
&orderTotal,
&fgs,
&glz,
&cardStatus,
&factoryCode,
&cardPwd,
&cardType,
&chgPwd );
ptr->Disconnect();
CoUninitialize();
}
LoadLibrary
#include <Windows.h>
#include "import.h"
#include "MainLoadLibrary.h"
extern "C"
{
typedef HRESULT (__stdcall *pFunc)(REFCLSID rclsid,REFIID riid,LPVOID * ppv);
}
void main_LoadLibrary(){
if (!SUCCEEDED(CoInitialize(NULL)))
{
return;
}
HINSTANCE hdllInst = LoadLibrary("E:\\YC.dll");
pFunc func=(pFunc)GetProcAddress(hdllInst,"DllGetClassObject");
if (func != NULL)
{
CLSID CLSID_SignCtrl_ocx;
HRESULT hr = CLSIDFromString(L"{5c4d3831-f09d-471b-82a0-0e84240c8afc}", &CLSID_SignCtrl_ocx);
if (!SUCCEEDED(hr))
{
return;
}
IClassFactory* pcf = NULL;
hr = func(CLSID_SignCtrl_ocx, IID_IClassFactory,(void**)&pcf);
if (SUCCEEDED(hr) && (pcf != NULL))
{
CLSID clsid;
clsid.Data1=0xfa7ab805;
clsid.Data2=0xec44;
clsid.Data3=0x4a84;
clsid.Data4[0]=0xb8;
clsid.Data4[1]=0x76;
clsid.Data4[2]=0x52;
clsid.Data4[3]=0xda;
clsid.Data4[4]=0x8a;
clsid.Data4[5]=0x5f;
clsid.Data4[6]=0xe3;
clsid.Data4[7]=0xc3;
_clsSmartCard* pCall = NULL;
hr = pcf->CreateInstance(NULL, clsid, (void**)&pCall);
if (SUCCEEDED(hr) && (pCall != NULL))
{
printf("Connect=%d", pCall->Connect("gouqi"));
VARIANT cardNo;
VARIANT customNo;
VARIANT orderdate;
VARIANT orderAmount;
VARIANT orderNum;
VARIANT orderTotal;
VARIANT fgs;
VARIANT glz;
VARIANT cardStatus;
VARIANT factoryCode;
VARIANT cardPwd;
VARIANT cardType;
VARIANT chgPwd;
::VariantInit(&cardNo);
::VariantInit(&customNo);
::VariantInit(&orderdate);
::VariantInit(&orderAmount);
::VariantInit(&orderNum);
::VariantInit(&orderTotal);
::VariantInit(&fgs);
::VariantInit(&glz);
::VariantInit(&cardStatus);
::VariantInit(&factoryCode);
::VariantInit(&cardPwd);
::VariantInit(&cardType);
::VariantInit(&chgPwd);
pCall->readCard(&cardNo,
&customNo,
&orderdate,
&orderAmount,
&orderNum,
&orderTotal,
&fgs,
&glz,
&cardStatus,
&factoryCode,
&cardPwd,
&cardType,
&chgPwd );
pCall->Disconnect();
}
pcf->Release();
} else{
printf("false");
}
}
FreeLibrary(hdllInst);
CoUninitialize();
getchar();
}
VS2010 开发 VB6.0 activeX控件 dll的更多相关文章
- 开发ActiveX控件调用另一个ActiveX系列1——开发一个MFC ActiveX控件
ActiveX开发的教程有很多,我也从中受益匪浅,例如以下这几篇: 基本教程:http://www.cnblogs.com/guenli/articles/1629915.html 注意事项:http ...
- 在VS2010中ActiveX控件注册方法,使用regsvr32命令
上一篇小编展示了如何设置VS2010自带的ActiveX控件的容器测试程序,现在为大家演示一下如何注册ActiveX控件. 首先简单了解一下ActiveX控件的知识,ActiveX控件:简单来说,就是 ...
- C#.NET开发ActiveX控件
最近刚开发了个activeX控件,下面是我的一些简单总结. 1. 先创建一个类库项目,在AssemblyInfo.cs设置 [assembly: ComVisible(true)] ,意思是使此程序集 ...
- VS2010如何生成ActiveX控件测试容器
VS2010中默认没有ActiveX控件测试容器TSTCON.exe,而是微软把这个文件放到了例子程序中,需要用户自己编译: 具体方法为: 在VS2010的安装目录中找到以下目录Samples\205 ...
- ActiveX控件(MFC篇)
目录 第1章 VC++6.0创建控件 1 1.1 目标 1 1.1.1 方法 1 1.1.2 属性 1 1.1.3 事件 1 1.2 创建项目 2 1.3 项目结构 ...
- ActiveX 控件
一.ActiveX基础 1.1什么是ActiveX ActiveX是COM规范的一种实现,前身是OLE(Object Linking and Embedding).一般读成:ActiveX Ctron ...
- Delphi 编写ActiveX控件(OCX控件)的知识和样例(有详细步骤)
一.ActiveX应用情况简介: ActiveX控件也就是一般所说的OCX控件,它是 ActiveX技术的一部分.ActiveX是微软公司推出的基于组件对象模型COM的技术,包括对Windows 32 ...
- 开发ActiveX控件调用另一个ActiveX系列0——身份证识别仪驱动的问题
程序员要从0下表开始,这篇是介绍这个系列的背景的,没有兴趣的人可以直接跳过. 为什么要开发ActiveX控件 由于工作需要,我们开发了一个网站,使用了一款身份证识别仪的网页ActiveX(OCX)插件 ...
- 【VS开发】在VS2010中开发ActiveX控件设置测试容器的方式
在VS2010中开发ActiveX控件设置测试容器的方式 借鉴文章http://blog.csdn.net/waxgourd0/article/details/7374669 在VS2010中开发MF ...
随机推荐
- golang函数
一.函数语法 func 函数名(形参列表) (返回值列表){ ...... return 返回值 } 例如: package main import "fmt" func test ...
- Django模板语言初识
一.Django框架简介 1.MVC框架 MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控 ...
- shell 基础(一)
废话少说 往下看 1. 查看 Shell Shell 是一个程序,一般都是放在/bin或者/user/bin目录下,当前 Linux 系统可用的 Shell 都记录在/etc/shells文件中./e ...
- python中logger模块的应用
logger模块是python内置的一个模块,主要用于输出运行日志,可以输出日志的等级,日志的保存路径等 具体详见博客https://www.cnblogs.com/qianyuliang/p/723 ...
- centos7搭建gitlab服务器、汉化
1.下载rpm安装包 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-8.8.5-ce.1.el7.x86_64.rp ...
- 【.net】未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序解决办法
#错误描述: 在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报错: “未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序” # ...
- java.util.ConcurrentModificationException异常原因及解决方法
在java语言中,ArrayList是一个很常用的类,在编程中经常要对ArrayList进行删除操作,在使用remove方法对ArrayList进行删除操作时,报java.util.Concurren ...
- java集合框架综述
一.集合框架图 简化图: 说明:对于以上的框架图有如下几点说明 1.所有集合类都位于java.util包下.Java的集合类主要由两个接口派生而出:Collection和Map,Collection和 ...
- DirectX11 With Windows SDK--20 硬件实例化与视锥体裁剪
前言 这一章将了解如何在DirectX 11利用硬件实例化技术高效地绘制重复的物体,以及使用视锥体裁剪技术提前将位于视锥体外的物体进行排除. 在此之前需要额外了解的章节如下: 章节回顾 18 使用Di ...
- cookie小栗子-实现简单的身份验证
关于Cookie Cookie是一种能够让网站Web服务器把少量数据储存到客户端的硬盘或内存里,或是从客户端的硬盘里读取数据的一种技术. 用来保存客户浏览器请求服务器页面的请求信息,可以在HTTP返回 ...