2009-06-05 8 views
4

Keine Frage, nur eine Aussage, um anderen zu helfen, die Stunden damit verbringen könnten, die Microchip PIC USB DLL richtig mit Unicode zu arbeiten.So rufen Sie Microchip PIC USB DLL mit Delphi 2009 auf

Es erwartet mehrere Zeichenketten, und obwohl diese einfach PAnsiChar sind, dauerte es die Ewigkeit, die richtige Kombination von DLL-Aufrufkonventionen zu bekommen. Es gibt eine Menge Leute im Netz, die Delphi (Nicht-Unicode) mit dieser DLL benutzen und mit Mord davonkommen.

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. 
+6

Hm ... Streng genommen, dann ist dies keine Frage. Ich denke nicht, dass es sinnvoll ist, es zu schließen, aber vielleicht solltest du das Gemeinsame machen und den Antwortteil bearbeiten. Dann poste das als eine tatsächliche Antwort und akzeptiere sie. – unwind

Antwort

1

Ich poste dies als vorläufige Antwort. @ Brian Frost kann den vollständigen Code veröffentlichen. Der Kern der Geschichte besteht darin, eine ANSI-Zeichenfolge mit einem Byte zu verwenden, wenn Sie mit einem Treiber zu tun haben, der dies erwartet.

StrPCopy(bufVendorProductID, AnsiString(AVendorProductID));