4

这不是一个问题,只是一个声明,以帮助任何可能花费数小时让 Microchip PIC USB DLL 与 Unicode 正常工作的人。

它需要几个字符串,虽然这些很简单PAnsiChar,但获得 DLL 调用约定的正确组合却花了我很多时间。网上有很多人使用带有此 DLL 的 Delphi(非 Unicode)并逃脱谋杀。

unit UArtPic32USBDriver;

interface

uses
  Windows,
  SysUtils,
  UArtGeneralHwDefs;


type
  EArtPic32Usb = class( EArtGeneralHw );

function Pic32Usb_GetDllVersion : integer;
// Returns a number representing the DLL version.

function Pic32Usb_GetDeviceCount( const AVendorProductID : string ) : integer;
// Returns the number of devices with this vendor ID

function Pic32Usb_Open(
           AInstance : DWORD;
           const AVendorProductID, AEndpointID : string;
           ADirectionCode : integer;
           ARaise         : boolean ) : THANDLE;
// Opens an endpoint. Can raise an exception if no valid handle is returned.


procedure Pic32Usb_Close( AHandle : THandle );
// Closes the device

function Pic32Usb_Write(
            AHandle              : THANDLE;
            ABufferPtr           : pointer;
            ALengthBytes         : integer ) : DWORD;
// Performs a write using this handle. Returns the number of bytes written

function Pic32Usb_Read(
            AHandle              : THANDLE;
            ABufferPtr           : pointer;
            ALengthBytes         : integer ) : DWORD;
// Performs a Read using this handle. Returns the number of bytes read

const
  MP_WRITE                   = 0;
  MP_READ                    = 1;

implementation



var

  _MPUSBGetDLLVersion  : function () :DWORD; cdecl stdcall;

  // Number of vid & pid matching USB Devices
  _MPUSBGetDeviceCount : function( pVID_PID : PAnsiChar ) : DWORD; cdecl;

  _MPUSBOpen           : function ( instance   : DWORD;
                                    pVID_PID   : PAnsiChar;
                                    pEP        : PAnsiChar;
                                    dwDir      : DWORD;
                                    dwReserved : DWORD ) : THANDLE; cdecl;

  _MPUSBClose          : function ( handle :THANDLE ) : DWORD; cdecl;

  _MPUSBRead           : function (     handle          : THANDLE;
                                        pData           : pointer;
                                        dwLen           : DWORD;
                                    var pLength         : DWORD;
                                        dwMilliseconds  : DWORD  ) : DWORD; cdecl;

  _MPUSBReadInt        : function (     handle         : THANDLE;
                                    var pData          : pointer;
                                        dwLen          : DWORD;
                                    var pLength        : PDWORD;
                                        dwMilliseconds : DWORD   ) : DWORD; cdecl;

  _MPUSBWrite          : function (     handle         : THANDLE;
                                        pData          : pointer;
                                        dwLen          : DWORD;
                                    var pLength        : DWORD;
                                        dwMilliseconds : DWORD ) : DWORD; cdecl;


  UsbDllHandle : THandle = 0;

const

  MillisecondPollingInterval = 100; //Represents 1 ms is hardware
  CharBufSize = 64;

type
  TAnsiCharBuf64 = array[0..CharBufSize-1] of AnsiChar;


function LoadDLL : THandle;
var
  S : string;
begin
  S := 'mpusbapi.dll';
  UsbDllHandle := LoadLibrary( PChar(S) );

  If UsbDllHandle = 0 then
     Raise EArtPic32Usb.CreateFmt(
       'The usb library is required but cannot be loaded. Check that it is installed. (%s)',
       [S]
        );

  @_MPUSBGetDLLVersion := GetProcAddress(UsbDllHandle,'_MPUSBGetDLLVersion');
  Assert(@_MPUSBGetDLLVersion <> nil);

  @_MPUSBGetDeviceCount := GetProcAddress(UsbDllHandle,'_MPUSBGetDeviceCount');
  Assert(@_MPUSBGetDeviceCount <> nil);

  @_MPUSBOpen := GetProcAddress(UsbDllHandle,'_MPUSBOpen');
  Assert(@_MPUSBOpen <> nil);

  @_MPUSBClose := GetProcAddress(UsbDllHandle,'_MPUSBClose');
  Assert(@_MPUSBClose <> nil);

  @_MPUSBRead := GetProcAddress(UsbDllHandle,'_MPUSBRead');
  Assert(@_MPUSBRead <> nil);

  @_MPUSBReadInt := GetProcAddress(UsbDllHandle,'_MPUSBReadInt');
  Assert(@_MPUSBReadInt <> nil);

  @_MPUSBWrite := GetProcAddress(UsbDllHandle,'_MPUSBWrite');
  Assert(@_MPUSBWrite <> nil);

  Result := UsbDllHandle;

end;

procedure NeedDLL;
begin
  If UsbDllHandle = 0 then
    LoadDll;
end;



function Pic32Usb_GetDllVersion : integer;
// Returns a number representing the DLL version.
begin
  NeedDLL;
  Result := _MPUSBGetDLLVersion();
end;


function Pic32Usb_GetDeviceCount( const AVendorProductID : string ) : integer;
// Returns the number of devices with this vendor ID
var
  bufVendorProductID : TAnsiCharBuf64;
begin
  NeedDLL;

  StrPCopy( bufVendorProductID, AnsiString(AVendorProductID) );

  Result := _MPUSBGetDeviceCount( @bufVendorProductID );
end;


function Pic32Usb_Open(
           AInstance : DWORD;
           const AVendorProductID, AEndpointID : string;
           ADirectionCode : integer;
           ARaise : boolean ) : THANDLE;
// Opens an endpoint. Can raise an exception if no valid handle is returned.
var
  bufVendorProductID, bufEndpointID : TAnsiCharBuf64;
begin
  NeedDLL;

  StrPCopy( bufVendorProductID, AnsiString(AVendorProductID) );
  StrPCopy( bufEndpointID, AnsiString(AEndpointID) );

  Result := _MPUSBOpen(
    AInstance,
    @bufVendorProductID,
    @bufEndpointID,
    DWORD(ADirectionCode),
    0 );

  if Result = 0 then
    If ARaise then
      Raise EArtPic32Usb.CreateFmt(
        'Unable to open USB device "%s", endpoint "%s"', [AVendorProductID, AEndpointID]);
end;


procedure Pic32Usb_Close( AHandle : THandle );
begin
  If UsbDllHandle <> 0 then
    _MPUSBClose( AHandle );
end;


function Pic32Usb_Write(
            AHandle              : THANDLE;
            ABufferPtr           : pointer;
            ALengthBytes         : integer ) : DWORD;
// Performs a write using this handle. Returns the number of bytes written
var
  I : integer;
begin
  I := _MPUSBWrite(
    AHandle,
    ABufferPtr,
    DWORD( ALengthBytes ),
    Result,
    MillisecondPollingInterval );
  if I <> 1 then
    Raise EArtPic32Usb.CreateFmt( 'Error performing USB write', []);
end;


function Pic32Usb_Read(
            AHandle              : THANDLE;
            ABufferPtr           : pointer;
            ALengthBytes         : integer ) : DWORD;
// Performs a Read using this handle. Returns the number of bytes read
var
  I : integer;
begin
  I := _MPUSBRead(
    AHandle,
    ABufferPtr,
    DWORD( ALengthBytes ),
    Result,
    MillisecondPollingInterval );
  if I <> 1 then
    Raise EArtPic32Usb.CreateFmt( 'Error performing USB read', []);
end;



initialization
finalization
  If UsbDllHandle <> 0 then
    FreeLibrary(UsbDllHandle)
end.
4

1 回答 1

1

我会将此作为临时答案发布。@Brian Frost 可以发布完整的代码。故事的要点是在处理需要它的驱动程序时使用单字节 ANSI 字符串。

StrPCopy( bufVendorProductID, AnsiString(AVendorProductID) );
于 2009-06-07T15:53:53.787 回答