目标:
在VBA(目前在VB环境下调试)环境下实现一段C++程序的功能。情景:
计算机连接一USB接收塔,等待外部传入信号。软件环境:
C++程序源代码。EXCEL XP, VB 6, VC++ 6, MSDN。USB接收塔驱动。
==================================================================问题1:VB中createfile()中的NULL指针传递C++代码:
#include <windows.h>    // For WIN32 supportconst char* szUsbTowerDeviceName = "\\\\.\\LEGOTOWER1";int main()
{
hUsbTower = CreateFile(szUsbTowerDeviceName, GENERIC_READ|GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
}VB代码:
Option Explicit
Const szUsbTowerDeviceName = "\\\\.\\LEGOTOWER1"'调用Win32 API
 Private Type SECURITY_ATTRIBUTES
        nLength As Long
        lpSecurityDescriptor As Long
        bInheritHandle As Long
 End Type Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long Private Const GENERIC_READ = &H80000000
 Private Const GENERIC_WRITE = &H40000000
 Private Const OPEN_EXISTING = 3'======
Dim hUsbTower As LongPrivate Sub Command1_Click()hUsbTower = CreateFile(UsbTowerDeviceName, GENERIC_READ Or GENERIC_WRITE, 0, (这个NULL指针怎么表达), OPEN_EXISTING, 0, 0)End Sub问题1 我的解决方案在上面VB代码的基础上加上如下代码:
Dim lpSA As SECURITY_ATTRIBUTESPrivate Sub Command1_Click()lpSA.nLength = 0
lpSA.lpSecurityDescriptor = 0
lpSA.bInheritHandle = FalsehUsbTower = CreateFile(UsbTowerDeviceName, GENERIC_READ Or GENERIC_WRITE, 0, lpSA, OPEN_EXISTING, 0, 0)End Sub自己评论:NULL指针能这么传么?===========================================================
问题2:VB中表达'&dwNewBytes'。获取地址?我也不知道怎么描述这个问题。
C++代码:
BYTE byBuffer[256];
DWORD dwBytes = 0;
DWORD dwNewBytes = 0;// See if there is a new byte of input available:
  dwNewBytes = 0;  if ((ReadFile(hUsbTower, byBuffer+dwBytes, 1, &dwNewBytes, NULL))
&&  (dwNewBytes > 0))
    { ... }VB代码:
Private Type OVERLAPPED
        Internal As Long
        InternalHigh As Long
        offset As Long
        OffsetHigh As Long
        hEvent As Long
End TypePrivate Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, _
ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As LongPrivate Sub Command1_Click()
  dwNewBytes = 0
  If ((ReadFile(hUsbTower, byBuffer + dwBytes, 1, (怎么写?‘AddressOf dwNewBytes’不对), (这个地方同问题1,‘Null’不能用))) And (dwNewBytes > 0)) Then
    ...
  End If
End Sub谢谢大家!

解决方案 »

  1.   

    关于问题1,我又有一种解决办法(只是通过VB语法检测)
    把lpSecurityAttributes由原来的SECURITY_ATTRIBUTES改设为Any
    这样就可以用ByVal 0&当做Null来用了。
    这个办法是我刚才搜04年前帖子的时候发现的。请问这行得通么?和我上面提出的方法有差别么?我想我可能不会用到SECURITY_ATTRIBUTES,它的作用是什么?
      

  2.   

    问题1:
    Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, Byval lpSecurityAttributes As long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As LonghUsbTower = CreateFile(UsbTowerDeviceName, GENERIC_READ Or GENERIC_WRITE, 0&, 0&, OPEN_EXISTING, 0&, 0&)问题2:
    Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, _
    ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, Byval lpOverlapped As Long) As LongIf ReadFile(hUsbTower, byBuffer + dwBytes, 1, dwNewBytes, 0&) Then
    if dwNewBytes then
      

  3.   

    用WinDriver可以直接生成读写码的 改一下
      

  4.   

    谢谢 homezj(小吉) 给出的方案。
    你好像把指针部分全部定义为Long类型了。能说明一下为什么么?^^>
    问题2中dwNewBytes原来是&dwNewBytes,我查了一下C++的帮助,&操作符在指针当中是获取对象的地址,能够在VB中省去么?或者只有在这种函数参数中才可以省去?也谢谢 fu0212(傅红雪),WinDriver是什么?^^b
      

  5.   

    fu0212(傅红雪),我查了WinDriver的介绍。关键是我要在Excel下面控制硬件,这个生成的代码是C的。我下载来试试。附:
    WinDriver 
     简 介 WinDriver 你也能自己写硬件的驱动程序 
    WinDriver 这支工具程序利用已经设计好的软件精灵,判断计算机上的硬件,然后使用者经过点选就能自动产生程序驱动的程序代码,减少硬件厂商开发的成本WinDriver 是一款 C/C++ 的工具组合,可以用来直接存取硬件,而不需要先写入装置驱动程序。使用者只要作了第一次使用的点选,往后就可以在平台上执行硬件。对于老旧硬件或有些网络上怎么找都遍寻不到的适配卡,就能使用它来控制你的硬件。 推荐人评价 使用者不需要事先了解任何核心或 OS 的知识。执行 WinDriver 时会先使用 Driver 精灵来诊断你计算机上的硬件种类,然后自动产生你的驱动程序码。它也包含对 PLX 和 Galileo PCI 芯片组的支持。这一版包含远程硬件存取能力,可让硬件的研发厂商在远程研发驱动程序、除错,节省铺货成本,且减少行销的时间。
      

  6.   

    WOW!!!!可以生成VB6代码!!!!
    研究!!!!:D!!!!
      

  7.   

    @@...完全看不懂。什么是Pipe?...其实我不要编驱动,因为已经有驱动了。我是要实现上面提到的C代码的功能。
      

  8.   

    homezj(小吉),你给的问题1的代码我试过了,无法得到成功开启通信的句柄。而我自己的方案是能得到句柄的。我是把lpSecurityAttributes按默认设成SECURITY_ATTRIBUTES。然后我定义一个lpSA as SECURITY_ATTRIBUTES,
    lpSA.nLength = 0
    lpSA.lpSecurityDescriptor = 0
    lpSA.bInheritHandle = FalsehUsbTower = CreateFile(UsbTowerDeviceName, GENERIC_READ Or GENERIC_WRITE, 0, lpSA, OPEN_EXISTING, 0, 0)
    这么操作之后,hUsbTower是能够正常返回非-1句柄的。
    按你说的设成Long之后,在原来Null的地方改成0&,每次返回结果都是-1。
    hUsbTower = CreateFile(szUsbTowerDeviceName, GENERIC_READ Or GENERIC_WRITE, 0, 0&, OPEN_EXISTING, 0, 0)
      

  9.   

    对不起homezj(小吉),你的代码我调试成功了。我再检查检查。可能我为了调试你代码新开的工程有问题,因为我直接在我原来的代码上按你说的修改成功了!:p顺便总结一下以上我自言自语的内容:
    1,问题:能否把CreateFile(),ReadFile()函数中的指针类型,Type类型,直接定义成Long而不是按默认的设置,比如SECURITY_ATTRIBUTES。
    2,我没理解fu0212(傅红雪) 的话,我去找来WinDriver,可是看不懂生成的VB工程。我不是要写驱动,我是要在EXCEL下用已有的驱动。