有读卡器的dll,如何制作成网页可以调用的activex,想请大神指点下

xia0sheng 2014-11-02 08:44:24
单位买了个一卡通的读卡器,读卡器厂家提供了dll,我直接用c++ 调用dll,读出卡号是没有问题的,现在是要做成网页可以调用这个函数,我在网上查资料,是用这个dll来制作activex 然后打包cab,让网页来调用这个函数,可是,我按这个教程http://blog.csdn.net/sdsky1987/article/details/6614409 制作,最后掉不出制作的函数,哪怕这个教程提供的add函数接口也加载不成功,有大神给指点下具体该怎么做吗?这个教程是不是哪里有问题,能帮忙给看看吗?

给单位做的,单位也没人懂,还请坛友帮忙下,拜谢了
...全文
671 21 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
图_钉 2014-12-15
  • 打赏
  • 举报
回复
开发一个ActiveX控件,MFC或ATL都可以,我也是最近遇到这个问题,我使用的是MFC C++开发的,一切OK。
wy24789 2014-12-06
  • 打赏
  • 举报
回复
跟踪调试下,看看哪里错了
laowang2 2014-12-06
  • 打赏
  • 举报
回复
用ATL做好点。
sailsxq 2014-12-05
  • 打赏
  • 举报
回复
说错了可以参考15楼, 或者DECLDIR int __stdcall Add( int a, int b ); 把__stdcall 去了,调用的地方 typedef int (__stdcall*AddFunc)(int,int); 也去掉__stdcall
sailsxq 2014-12-05
  • 打赏
  • 举报
回复
DECLDIR int __stdcall Add( int a, int b ); 把__stdcall 去了,调用的地方不用改。 activex 以及cab打包参考下面这个 http://blog.csdn.net/hzzhoushaoyu/article/details/6604572 http://blog.csdn.net/hzzhoushaoyu/article/details/7354180 这有activex 完整的教程 http://www.codeproject.com/Articles/22185/A-Complete-Scriptable-ActiveX-Web-Control-Tutorial 另外你要做的哥也正在做
sailsxq 2014-12-05
  • 打赏
  • 举报
回复
DECLDIR int __stdcall Add( int a, int b ); 把__stdcall 去了,调用的地方不用改。 activex 以及cab打包参考下面这个 http://blog.csdn.net/hzzhoushaoyu/article/details/6604572 http://blog.csdn.net/hzzhoushaoyu/article/details/7354180 这有activex 完整的教程 http://www.codeproject.com/Articles/22185/A-Complete-Scriptable-ActiveX-Web-Control-Tutorial 另外你要做的哥也正在做
zhdhj 2014-11-06
  • 打赏
  • 举报
回复
问题出在dll_test1中的Add函数的导出名称变成了_Add@8 你把_AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add"); 改成 _AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "_Add@8"); 应该可以了。
xia0sheng 2014-11-06
  • 打赏
  • 举报
回复
引用 13 楼 astrostar 的回复:
读卡器的DLL 函数也分 C/S版和B/S版 ,先确认
这个我还真没问 只给的dll还分这么细吗?我直接用 vc++ 调用给的接口函数 能读出卡号,下面做的activex不就是B/S吗? 难道给dll的时候也分? 我现在想先实现这个加法器,这个小例子都没成功,所以这个例子的失败暂时和读卡器dll没关系
astrostar 2014-11-06
  • 打赏
  • 举报
回复
读卡器的DLL 函数也分 C/S版和B/S版 ,先确认
xia0sheng 2014-11-06
  • 打赏
  • 举报
回复
引用 9 楼 zhdhj 的回复:
看了你贴的代码,感觉错误不在Activex,是 _AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add"); 这句话出问题了,是_AddFunc 的值为Null,没有能定位到Add这个导出函数,建议你查下加载dll_test1.dll后hInstLibrary有没有值,如果有值再看下dll中的导出函数的名称是否是“Add”,这个可以用VC自带的Dumpbin /exports dll名称 进行查看。

导出dll_test1 的结果如下:


导出testweb1.dll的结果如下:


好像dll_test1里能看到Add函数,testweb1.dll看不到Add函数,是说这里出问题了吗?需要把 dll_test1.dll和testweb1.dll都放在c:\windows\system32下面吗? 昨天给一个网上的人看了下这些代码,他回答说,整个流程没有问题,但是中间有很多错误,不过没告诉我具体哪里错了,他也指出了LoadLibrary 这个函数用的有问题,说最好不要用显式调用 ,要用隐式调用?但是我的读卡器只给我了dll,求继续指教,谢谢了
zhdhj 2014-11-05
  • 打赏
  • 举报
回复
如果在本地测试,你先不要用object这个标签,你先用obecjtactivex 方法测试下你的 activex,因为我刚才看了下参考的网址,是教你做activex 组件的,并不是做activex 控件。所以,你可以用下面代码测试下创建的对象a是不是空,可以在IE里按F12对js调试 <script type="text/javascript"> var a = new ActiveXObject("IEWebSer.IWebSer.1"); alert(a.WebSerHttp("1111","22222")); </script> 其中 “IEWebSer.IWebSer.1” 是progID,具体你创建的activex的pgrogID,可以到你项目的一个rgs中找 ProgID = 这句话,如果只要你网页不在用,应该没错编译都可以注册成功,如果是在Vista以上的系统,需要以管理员权限运行VS,然后编译的时,才有权限注册成功。或者在具有管理员权限的命令行下 运行 regsvr32 加上你的activex全路径名 看看注册是否成功。
xia0sheng 2014-11-05
  • 打赏
  • 举报
回复
引用 10 楼 zhdhj 的回复:
Activex中也缺少一个IObjectSafetyImpl 接口,否则IE在一般安全设置下也会阻止Activex运行的。
这个程序里可能没写 给的例子里有些这句 public IObjectSafetyImpl<Ctest_op, INTERFACESAFE_FOR_UNTRUSTED_CALLER| INTERFACESAFE_FOR_UNTRUSTED_DATA>,
xia0sheng 2014-11-05
  • 打赏
  • 举报
回复
引用 4 楼 yeah2000 的回复:
将证书安装在本地可信任区域里
在网上找了个测试例子,前面函数调用都出问题了,我尝试下解决下吧
zhdhj 2014-11-05
  • 打赏
  • 举报
回复
Activex中也缺少一个IObjectSafetyImpl 接口,否则IE在一般安全设置下也会阻止Activex运行的。
zhdhj 2014-11-05
  • 打赏
  • 举报
回复
看了你贴的代码,感觉错误不在Activex,是 _AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add"); 这句话出问题了,是_AddFunc 的值为Null,没有能定位到Add这个导出函数,建议你查下加载dll_test1.dll后hInstLibrary有没有值,如果有值再看下dll中的导出函数的名称是否是“Add”,这个可以用VC自带的Dumpbin /exports dll名称 进行查看。
xia0sheng 2014-11-05
  • 打赏
  • 举报
回复
引用 6 楼 zhdhj 的回复:
如果在本地测试,你先不要用object这个标签,你先用obecjtactivex 方法测试下你的 activex,因为我刚才看了下参考的网址,是教你做activex 组件的,并不是做activex 控件。所以,你可以用下面代码测试下创建的对象a是不是空,可以在IE里按F12对js调试
<script type="text/javascript">
var a = new ActiveXObject("IEWebSer.IWebSer.1");
alert(a.WebSerHttp("1111","22222"));
</script>
其中 “IEWebSer.IWebSer.1” 是progID,具体你创建的activex的pgrogID,可以到你项目的一个rgs中找 ProgID = 这句话,如果只要你网页不在用,应该没错编译都可以注册成功,如果是在Vista以上的系统,需要以管理员权限运行VS,然后编译的时,才有权限注册成功。或者在具有管理员权限的命令行下 运行 regsvr32 加上你的activex全路径名 看看注册是否成功。


引用 6 楼 zhdhj 的回复:
如果在本地测试,你先不要用object这个标签,你先用obecjtactivex 方法测试下你的 activex,因为我刚才看了下参考的网址,是教你做activex 组件的,并不是做activex 控件。所以,你可以用下面代码测试下创建的对象a是不是空,可以在IE里按F12对js调试
<script type="text/javascript">
var a = new ActiveXObject("IEWebSer.IWebSer.1");
alert(a.WebSerHttp("1111","22222"));
</script>
其中 “IEWebSer.IWebSer.1” 是progID,具体你创建的activex的pgrogID,可以到你项目的一个rgs中找 ProgID = 这句话,如果只要你网页不在用,应该没错编译都可以注册成功,如果是在Vista以上的系统,需要以管理员权限运行VS,然后编译的时,才有权限注册成功。或者在具有管理员权限的命令行下 运行 regsvr32 加上你的activex全路径名 看看注册是否成功。


你这个方法我暂时还没试,我还是在尝试上面给的链接http://blog.csdn.net/sdsky1987/article/details/6614409 里制作加法器的例子,我制作了个测试程序,但是现在在调用这个程序的时候还是会出错,麻烦您给看下问题出在哪里了可以吗?基本上就是这个链接的流程,我把我的代码贴下:
首先是制作加法器的dll,我的项目名称是dll_test1 代码如下
头文件 testdll.h
#ifndef _DLLTUT_DLL_H_  

#define _DLLTUT_DLL_H_

#if defined DLL_EXPORT

#define DECLDIR __declspec(dllexport)

#else

#define DECLDIR __declspec(dllimport)

#endif

extern "C" //告诉编译器该部分可以在C/C++中使用。

{

DECLDIR int __stdcall Add( int a, int b );

DECLDIR void Function( void );

}

#endif


cpp文件 testdll.cpp
#include <iostream>  

#define DLL_EXPORT

#include "testdll.h"

extern "C"

{

DECLDIR int __stdcall Add( int a, int b )

{

return( a + b );

}

DECLDIR void Function( void )

{

std::cout << "DLL Called!" << std::endl;

}

}


第二个项目是testweb1,调用dll_test1.dll制作alt activex,源代码如下:
头文件test_top
#pragma once
#include "resource.h" // 主符号



#include "testweb1_i.h"
#include "_Itest_opEvents_CP.h"



#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。"
#endif

using namespace ATL;


// Ctest_op

class ATL_NO_VTABLE Ctest_op :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<Ctest_op, &CLSID_test_op>,
public IConnectionPointContainerImpl<Ctest_op>,
public CProxy_Itest_opEvents<Ctest_op>,
public IObjectWithSiteImpl<Ctest_op>,
public IDispatchImpl<Itest_op, &IID_Itest_op, &LIBID_testweb1Lib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
typedef int (__stdcall*AddFunc)(int,int); //类型定义,对应DLL ADD方法。Func自定义,随便写。

HINSTANCE hInstLibrary;

AddFunc _AddFunc; //类映射
Ctest_op()
{
//开始调用DLL,进行计算。

hInstLibrary = ::LoadLibrary(L"C:\\Users\\xia0sheng\\Desktop\\ceshi\\dll_test1\\Debug\\dll_test1.dll");//把写好的dll_test.dll文件放在此项目生成的目录debug下。

//小哆觉得这应该就是相对路径的成功应用了。以后打包时,因为一直在同一路径下,所以,只要同时移动就不会出问题。

if (hInstLibrary == NULL)

{

FreeLibrary(hInstLibrary);//资源释放

}else{

}

//调用方法,返回方法句柄。

_AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add");
}

DECLARE_REGISTRY_RESOURCEID(IDR_TEST_OP)


BEGIN_COM_MAP(Ctest_op)
COM_INTERFACE_ENTRY(Itest_op)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY(IObjectWithSite)
END_COM_MAP()

BEGIN_CONNECTION_POINT_MAP(Ctest_op)
CONNECTION_POINT_ENTRY(__uuidof(_Itest_opEvents))
END_CONNECTION_POINT_MAP()


DECLARE_PROTECT_FINAL_CONSTRUCT()

HRESULT FinalConstruct()
{
return S_OK;
}

void FinalRelease()
{
}

public:



STDMETHOD(GetContent)(LONG a, LONG b, LONG* out);
};

OBJECT_ENTRY_AUTO(__uuidof(test_op), Ctest_op)


cpp文件 test_top.cpp
[#include "stdafx.h"
#include "test_op.h"
#include <iostream>
using namespace std;


// Ctest_op



STDMETHODIMP Ctest_op::GetContent(LONG a, LONG b, LONG* out)
{
// TODO: 在此添加实现代码
int sum = _AddFunc(static_cast<int>(a),static_cast<int>(b));
*out = long(sum);

return S_OK;
}/code]

第三个项目,是调用制作成的active 项目名称是验证,源代码如下:
[code=c]#include "stdafx.h"
#include "C:\Users\xia0sheng\Desktop\ceshi\testweb1\testweb1\testweb1_i.h"

#include "C:\Users\xia0sheng\Desktop\ceshi\testweb1\testweb1\testweb1_i.c"

#include <iostream>

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr;

Itest_op *IFirstATL = NULL;

// Now we will intilize COM

hr = CoInitialize(0);

// Use the SUCCEDED ro and see if we can get a pointer to

// the interface

if(SUCCEEDED(hr))

{

hr = CoCreateInstance( CLSID_test_op, NULL, CLSCTX_INPROC_SERVER, IID_Itest_op, (void**) &IFirstATL);

// If we succeeded then call the AddNumbers method, if it failed

// then display an appropriate message to the user.

if(SUCCEEDED(hr))

{

long ReturnValue;

hr = IFirstATL->GetContent(5, 7, &ReturnValue);

cout << "The answer for 5 + 7 is: " << ReturnValue << endl;


hr = IFirstATL->Release();

}

else

{

cout << "CoCreateInstance Failed." << endl;

}

}

// Uninitialize COM

CoUninitialize();

system("pause");
return 0;
}



我执行最后这个验证项目的时候,跳到testweb1.cpp 里会出现如下报错

我都是按教程来的,是在不知道为什么会出现错误,我对c++ 也不对特别熟悉,麻烦能给看下原因嘛?谢谢了,弄了一周多了,这个activex还没弄成功 谢谢
xia0sheng 2014-11-05
  • 打赏
  • 举报
回复
引用 5 楼 xia0sheng 的回复:
[quote=引用 4 楼 yeah2000 的回复:] 将证书安装在本地可信任区域里
在网上找了个测试例子,前面函数调用都出问题了,我尝试下解决下吧[/quote] 非常非常感谢 我试下
xia0sheng 2014-11-04
  • 打赏
  • 举报
回复
引用 2 楼 zhdhj 的回复:
如果你的网页在另一台机器上运行,那cab包需要数字签名的,否则IE都拒绝下载,并且在object的codebase属性中告诉cab的下载地址;如果网页就在开发机上查看下那你的activex有没有注册成功呢。
好像是没有注册成功,因为重复编辑这个程序,所以名字都一样,好像如果之前注册过,之后注册默认不成功,现在的问题是,我有点不知道该怎么找问题出现在哪里,网页调用不成功,不知道哪里出问题了 又无法验证。 我暂时先在本地实验,不制作签名可以吧?我把ie浏览器 安全都设置最低了 允许未签名的activex 通过,加载网页的时候 也提示安装activex 也安装了 可是调用 activex的时候 提示无效 求指点该怎么做 如果可以 帮忙看下那个链接里 制作步骤有没有问题
yeah2000 2014-11-04
  • 打赏
  • 举报
回复
将证书安装在本地可信任区域里
xia0sheng 2014-11-03
  • 打赏
  • 举报
回复
有达人帮忙解答下吗 感谢
加载更多回复(1)

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧