Bilbioteka VB oraz Delphi

0

Witam. Mam prosty program do obsługi pololu maestro czyli serwokontrolera usb pod VB. Problem w tym że nie potrafię tego języka, również nie potrafiłem napisać takiego pod Delphi ani jego na to przetłumaczyć. Pomyślałem że ów program zapiszę jako bilbioteke .dll i ją ewentualnie modyfikując, a w Delphi bym robił resztę. Zrobiłem jako libary, zapisałem do .dll i załadowałem w Delphi tak dając przykładową funkcje przy przetestować:

procedure TForm1.Button1Click(Sender: TObject);
var
  DLL : THandle; // uchwyt biblioteki
  ShowForm : procedure;
begin
  DLL := LoadLibrary('MaestroEasyExampleVb.dll'); // laduj biblioteke
  try
    @ShowForm := GetProcAddress(DLL, 'TrySetTarget(0, 0)'); // laduj procedure
    if @ShowForm=nil then raise Exception.Create('Bład - nie mogę znaleźć proceudry w bibliotece!');
    ShowForm; // wywolaj procedure
  finally
    FreeLibrary(DLL); // wreszcie zwolnij pamiec
  end;
end;

Nie ważne czy bilbioteka jest czy jej nie ma, jaką funkcje wpisze to i tak za każdym razem wyskakuje "Bład - nie mogę znaleźć proceudry w bibliotece!". Użyłem TrySetTarget(0, 0) bo taka też jest w kodzie VB. Tutaj kod mojej bilbioteki .dll:

'  MaestroEasyExampleVb:
'    Simple example GUI for the Maestro USB Servo Controller, written in
'    Visual Basic .NET.
'    
'    Features:
'       Temporary native USB connection using Usc class.
'       Button for disabling channel 0.
'       Button for setting target of channel 0 to 1000 us.
'       Button for setting target of channel 0 to 2000 us.
' 
'  NOTE: Channel 0 should be configured as a servo channel for this program
'  to work.  You must also connect USB and servo power, and connect a servo
'  to channel 0.  If this program does not work, use the Maestro Control
'  Center to check what errors are occurring.

Imports Pololu.UsbWrapper
Imports Pololu.Usc

Imports System
Imports System.Text
Imports System.ComponentModel

Public Class MainWindow
    ''' <summary>
    ''' This subroutine runs when the user clicks the Target=1000us button.
    ''' </summary>
    Sub Button1000_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1000.Click
        TrySetTarget(1, 1000 * 4) ' Set the target of channel 0 to 1000 microseconds.
    End Sub

    ''' <summary>
    ''' This subroutine runs when the user clicks the Target=2000us button.
    ''' </summary>
    Sub Button2000_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button2000.Click
        TrySetTarget(1, 2000 * 4) ' Set the target of channel 0 to 2000 microseconds.
    End Sub

    ''' <summary>
    ''' This function runs when the user clicks the Disable button.
    ''' </summary>
    Sub ButtonDisable_Click(ByVal sender As Object, ByVal e As EventArgs) Handles ButtonDisable.Click
        ' Set target of channel 0 to 0.  This tells the Maestro to stop
        ' transmitting pulses on that channel.  Any servo connected to it
        ' should stop trying to maintain its position.
        TrySetTarget(0, 0)
    End Sub

    ''' <summary>
    ''' Attempts to set the target of 
    ''' </summary>
    ''' <param name="channel">Channel number from 0 to 23.</param>
    ''' <param name="target">
    '''   Target, in units of quarter microseconds.  For typical servos,
    '''   6000 is neutral and the acceptable range is 4000-8000.
    ''' </param>
    Sub TrySetTarget(ByVal channel As Byte, ByVal target As UInt16)
        Try
            Using device As Usc = connectToDevice() ' Find a device and temporarily connect.
                device.setTarget(channel, target)
                ' device.Dispose() is called automatically when the "Using" block ends,
                ' allowing other functions and processes to use the device.
            End Using
        Catch exception As Exception  ' Handle exceptions by displaying them to the user.
            displayException(exception)
        End Try
    End Sub

    ''' <summary>
    ''' Connects to a Maestro using native USB and returns the Usc object
    ''' representing that connection.  When you are done with the
    ''' connection, you should close it using the Dispose() method so that
    ''' other processes or functions can connect to the device later.  The
    ''' "Using" statement can do this automatically for you.
    ''' </summary>
    Function connectToDevice() As Usc
        ' Get a list of all connected devices of this type.
        Dim connectedDevices As List(Of DeviceListItem) = Usc.getConnectedDevices()

        For Each dli As DeviceListItem In connectedDevices
            ' If you have multiple devices connected and want to select a particular
            ' device by serial number, you could simply add some code like this:
            '    If dli.serialNumber <> "00012345" Then
            '        Continue For
            '    End If

            Dim device As Usc = New Usc(dli)  ' Connect to the device.
            Return device                     ' Return the device.
        Next

        Throw New Exception("Could not find device.  Make sure it is plugged in to " & _
            "USB and check your Device Manager.")
    End Function

    ''' <summary>
    ''' Displays an exception (error) to the user by popping up a message box.
    ''' </summary>
    Sub displayException(ByVal exception As Exception)
        Dim stringBuilder As StringBuilder = New StringBuilder()
        Do
            stringBuilder.Append(exception.Message & "  ")
            If TypeOf exception Is Win32Exception Then
                Dim win32Exception As Win32Exception = DirectCast(exception, Win32Exception)
                stringBuilder.Append("Error code 0x" + win32Exception.NativeErrorCode.ToString("x") + ".  ")
            End If
            exception = exception.InnerException
        Loop Until (exception Is Nothing)
        MessageBox.Show(stringBuilder.ToString(), Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Sub

End Class

Co tutaj jest błędne w kodzie delphi lub vb? Wcześniej próbowałem od razu załadować bilbiotekę usc.dll która jest używana w kodzie vb z przykładową funkcją "getConnectedDevices()" i to samo, za każdym razem ten błąd, dlatego właśnie postanowiłem zrobić bilbioteke z VB skoro kod mam gotowy i bez tłumaczenia załadować do delphi. Co mam zrobić?

Proszę o pomoc

0

Nie znam się na VB ale widzę że robisz błąd przy ładowaniu biblioteki. Powinno to wyglądać jakoś tak:

type
  //TTrySetTarget = function(channel: Byte; target: Word): ????
  //co to ustrojstweo tam zwraca w tym VB wyglada na procedure
  TTrySetTarget = procedure(channel: Byte; target: Word); stdcall;
//
//ciach
//
procedure TForm1.Button1Click(Sender: TObject);
var
  hDLL : THandle; // uchwyt biblioteki
  ShowForm: TTrySetTarget;
begin
  hDLL := LoadLibrary('MaestroEasyExampleVb.dll'); // laduj biblioteke
  try
    @ShowForm := GetProcAddress(hDLL, 'TrySetTarget'); // laduj procedure
    if not Assigned(ShowForm) then raise Exception.Create('Bład - nie mogę znaleźć proceudry w bibliotece!');
    ShowForm(0, 0); // wywolaj procedure <-- co to robi, czy możesz zaraz po tym zwolnić bibliotekę?
  finally
    FreeLibrary(hDLL); // wreszcie zwolnij pamiec
  end;
end;
0

Dzięki za chęć pomocy niestety nadal ten sam błąd. Tutaj gotowa bilbioteka: http://www.sendspace.com/file/n1gnls

A tutaj biblioteka która wykorzystywana jest w VB. Najlepiej było by bezpośrednio połączyć się z nią no ale też nie potrafię, nie radzę sobie z dll :/ http://www.sendspace.com/file/ydgh9u

0

Przecież ta biblioteka nie eksportuje żadnych funkcji. Musisz pierwsze poprawnie napisać dll'kę ale w tym nie pomogę (nie znam VB).

0

No ok ale usc.dll którą dołączyłem w poprzednim poście już ma funkcje które były użyte w VB i też bez skutku, ona na pewno jest dobrze napisana.

0

To kawałek źródła usc.dll

 public String firmwareVersionString
        {
            get
            {
                return firmwareVersionMajor.ToString() + "." + firmwareVersionMinor.ToString("D2");
            }
        }

Dlatego wpisując delphi
@ShowForm := GetProcAddress(hDLL, 'firmwareVersionString');
nie powinno być błędu, no ale jednak jest...

0

Coś mi się wydaje że Delphi nie będzie współpracowało "normalnie" z bibliotekami napisanymi VB (taka biblioteka nie ma normalniej tabeli exportów dlatego GetProcAddress nie działa). Prawdopodobnie trzeba by się bawić w COM lub coś w tym stylu :/

0

Trudno, udało mi się odpalić ten gotowy projekt w c++ więc zacznię jego się uczyć, bo wydaje mi się prostszy od VB ale jednak Delphi łatwiej łapie.

0

daj kod z c++ to może ktoś Ci pomoże przetłumaczyć go na delphi

0

O, było by świetnie, bardzo o to proszę. Aby czegoś nie brakowało to wrzucam dały katalog: http://www.sendspace.com/file/t6dvuu

Pozdrawiam

Jakby coś jeszcze to GG: 5569666, mail [email protected]

0

i będzie coś z tego ? :(

1 użytkowników online, w tym zalogowanych: 0, gości: 1