VB6.0新建一ACTIVEX DLL工程(工程名CreditCardCheckDll、类名CreditCardCheck),代码如下(主要完成信用卡号的验证操作)Dim intNumber As Integer
Dim strNumberFinal As String
Dim intSum As Integer
Dim validLuhn As Boolean
Public Function fnValidateCreditCard(strCCNumber As String) As Boolean
    MsgBox strCCNumber'调试用,用来显示传入的参数
    If fnLengthCheck(strCCNumber) And fnLuhnCheck(strCCNumber) Then
       fnValidateCreditCard = True
    Else
        fnValidateCreditCard = False
    End If
End FunctionPrivate Function fnLengthCheck(strCCNumber As String) As Boolean
    Dim validLength As Boolean
    validLength = False
    If Len(strCCNumber) = 16 Then
        validLength = True
    Else
        validLength = False
    End If
    fnLengthCheck = validLength
End FunctionPrivate Function fnLuhnCheck(strCCNumber As String) As Boolean'为银行界信用卡号通用算法
    Dim strRev As String
    Dim strCh As String
    Dim intNumber As Integer
    Dim strNumberFinal As String
    Dim intSum As Integer
    Dim validLuhn As Boolean
    strRev = StrReverse(strCCNumber)
    For intTemp = 1 To Len(strRev)
        strCh = Mid(strRev, intTemp, 1)
        intNumber = CInt(strCh)
        If intTemp Mod 2 = 0 Then
            intNumber = intNumber * 2
            If intNumber > 9 Then
                intNumber = intNumber - 9
            End If
        End If
        strNumberFinal = strNumberFinal & intNumber
    Next intTemp
    If intSum Mod 10 = 0 Then
        validLuhn = True
    Else
        validLuhn = False
    End If
    fnLuhnCheck = validLuhn
End Function/////////////////////////////////////////////////////////////
VB中新建一工程对其进行测试(界面为一文本框一按钮)Private Sub Command1_Click()Dim obj As CreditCardCheckDll.CreditCardCheck
Set obj = New CreditCardCheckDll.CreditCardCheckMsgBox Text1.Text'显示一下传递的参数If obj.fnValidateCreditCard(Text1.Text) = True Then
    MsgBox "ok"
Else
    MsgBox "no"
End IfEnd Sub测试;用有效卡号4567890123456783进行测试,显示ok
用无效卡号4567890123456789进行测试,显示noVB测试通过///////////////////////////////////////////////////////////////////
现在用VC基于对话框工程对VB组件进行测试(界面同样为一文本框一个按钮)
三步工作如下
1、在stdafx.h文件下引入VB组件并编绎stdafx.cpp文件
#import "h:\CreditCardCheck\CreditCardCheckDll.dll"//为绝对路径
2、在Dlg.cpp文件顶部使用名字空间
using namespace CreditCardCheckDll;
3、添加按钮事件如下
void CZjyDlg::OnButton1() 
{
// TODO: Add your control notification handler code here
HRESULT hr=CoInitialize(NULL);
CLSID clsid;
hr=CLSIDFromProgID(OLESTR("CreditCardCheckDll.CreditCardCheck"),&clsid);
_CreditCardCheck * ckptr;
hr=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,__uuidof(_CreditCardCheck),(LPVOID *)&ckptr);

if(FAILED(hr))
{
AfxMessageBox("failed");
return;
} char cCardNum[20];
GetDlgItemText(IDC_EDIT1,cCardNum,20); BSTR bstCardNum=_bstr_t(cCardNum); CString str(bstCardNum);
AfxMessageBox(str); long lStatus;
lStatus=ckptr->fnValidateCreditCard(&bstCardNum);
if(lStatus==1)
AfxMessageBox("ok");
else
AfxMessageBox("no");
}
编绎通过,可是进行测试时不论是有效卡号,还是无效卡号,都是显示
AfxMessageBox("no");
请问我的代码问题出在哪里?(附VB组件绝对正确,因为VB进行测试通过)

解决方案 »

  1.   

    After lStatus=ckptr->fnValidateCreditCard(&bstCardNum);
    Do a AfxMessageBox(lStatus);
    Make sure that lStatus changes and is 1 for true.  To my knowledge, in VB -1 is true.  So check if lStatus changes from the DLL call.
      

  2.   

    VB、VC中TRUE和FALSE是不一致的,看看下面的文章:在VB、VC中不一致的TRUE和FALSE 作者: 盛放
    Monday, November 4 2002 11:19 AM 
      
    无论是用VB编程,还是用VC编程,大家对布尔类型非常熟悉了,可是大家是否注意到这布尔类型在VB和VC中的不同之处?请看如下代码: UINT MakePdu(BOOL b)
    {
     if (b==TRUE)
       AfxMessageBox("TRUE");
     else
       AfxMessageBox("FASLE");
     return 1;
    }
    这是一段非常简单的代码,根据布尔类型参数分别弹出不同的对话框,如果你只是在VC中使用这段代码,那么不会有问题,可是,如果你制作成DLL提供给VB调用,那么就会发现问题了(其实我个人认为这段代码还存在一个比较大的问题)。用VC新建一个WIN32 DLL工程:BlDll,加入上面那段代码(记得在函数申明中加入 WINAPI),在DEF文件中EXPORTS后加入MAKEPDU以导出函数,编译生成BLDLL.DLL文件。用VB新建一个标准EXE:TSTBLDLL,在窗体加入一个按钮,然后增加如下代码:Private Declare
    Function MakePdu Lib "BLDL.dll" (ByVal b As Boolean) As Integer
    (如果你不喜欢将DLL拷贝到系统目录下,那么应该加上文件所在的目录名)Private Sub Command1_Click()
    MakePdu True
    MakePdu False
    End Sub这段代码也非常简单,申明MAKEPDU函数,然后在点击按钮中调用,传递VB的布尔类型作为参数。根据上面的VC代码,我们可以预测到按下按钮后应该先弹出TRUE的对话框,再弹出FALSE对话框。那么请按下按钮吧。很吃惊吧,让你失望了,弹出的是两个FALSE对话框!现在让我们开始调试DLL找出原因。首先关掉VB(当然要保存工程文件)在VC的if (b==TRUE)处按下F9键设置断点,然后按下F5键开始执行DLL,当然DLL不能执行,VC会提示选择一个执行文件进行调试,选择VB6.EXE。在VB中打开TSTBLDLL工程,运行并按下按钮。在VC中你会发现原来VB传过来的True并不是如同想象中一样是1,而是0xffffffff。现在真相大白了,在VC中布尔类型的TRUE就是1,而在VB中却是-1!因此我们在编制VC动态连接库提供VB调用时,请注意不要使用布尔类型,用别的类型进行替代。其实有一个更简单的解决办法,因为不论是VC还是VB,都会把0认为是FALSE,其他非0值认为是TRUE,因此只要把if (b==TRUE)改为if(b)也可以让程序执行正常。但是本人保留这种做法,一个从代码角度来讲,对于别人使用上,很容易让人产生混淆,究竟是满足那种条件代表TRUE呢?另外一个在可扩充性上比较差,因为使用BOOL意味着只能满足两种条件,如果以后条件进行了扩展,布尔类型就没有办法解决了。当然,这只是我个人的看法,希望和大家讨论。 
      

  3.   

    帮楼主调试了一下,以下代码应该是正确的示范:)void CTestDlg::OnButton1() 
    {
    // TODO: Add your control notification handler code here
    HRESULT hr=CoInitialize(NULL);
    CLSID clsid;
    hr=CLSIDFromProgID(OLESTR("CreditCardCheckDll.CreditCardCheck"),&clsid);
    _CreditCardCheck * ckptr;
    hr=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,__uuidof(_CreditCardCheck),(LPVOID *)&ckptr);

    if(FAILED(hr))
    {
    AfxMessageBox("failed");
    return;
    } char cCardNum[20];
    GetDlgItemText(IDC_EDIT1,cCardNum,20); BSTR bstCardNum=_bstr_t(cCardNum); CString str(bstCardNum);
    AfxMessageBox(str); long lStatus;
    lStatus=ckptr->fnValidateCreditCard(&bstCardNum);
    if(lStatus==-1)//修改这一行
    AfxMessageBox("ok");
    else
    AfxMessageBox("no");
    CoUninitialize();//加上这一句
    }
      

  4.   

    建议楼主bool 类型的都转成int 类型的数据传送
    string 和对象都使用 variant 类型传送