Hallöchen,
wir haben hier einen Kunden, der eine PCI-Karte der Firma Leetro
(MPC2810, siehe www.leetro.com) einsetzt. Die Karte ist soweit ganz nett
(4 Achsen, viele I/O-Ports usw.). Das alles soll in eine
Selbstbaumaschine (ist aber nicht unser Part).
Er kommt damit aber gar nicht zurecht und hat mich nun gebeten, der
Karte zumindest etwas zu entlocken und ihm dann zu erklären, wie er
selbst weiterkommt ...
Auch meine Antwort, dass ich schon Ewigkeiten (15 Jahre!) nicht mehr
unter Windows (erst Recht nicht mit VB) hardwarenah gearbeitet habe,
konnte ihn nicht schrecken. Toll. Kunde möchte unbedingt Basic, damit er
das später auch kann (naja ...)
Ist aber ein sehr guter Kunde und ich hab versprochen, mich da mal
hinterzuklemmen.
Es geht also vermutlich um ein klassisches DAU-Problem.
Stand im Moment: es läuft hier auf dem Testrechner ein WinXP, PCI-Karte
ist verbaut und läuft soweit mit Treiber und Demoprogrammen des
Herstellers, gibt auch messbar Schritte etc. aus.
Installiert habe ich mir hier Visual Basic 2010 Express.
Ich habe mir ein kleines Projekt erstellt und den obligatorischen Button
mit dem Click-Event und "Hallo, Welt!" gebaut. Läuft.
So, jetzt möchte ich die Hersteller-DLL (MPC2810.dll) einbinden. Der
Hersteller liefert für die Basic-Anbindung zusätzlich eine Basic-Datei,
die ich so interpretiere, dass dort quasi die Funktionsdeklarationen der
DLL stehen (siehe Anhang):
-----------
Attribute VB_Name = "FunctionDeclare"
Option Explicit
Declare Function auto_set Lib "MPC2810" () As Long
Declare Function init_board Lib "MPC2810" () As Long
usw.
-----------
Ich habe die nun in meine Klasse übernommen und rufe die beim Anklicken
des Buttons auf. Die beiden Funktionen sollten dann einmal die Anzahl
der Karten (=1) und die Anzahl der Achsen (=4) zurückgeben - stattdessen
werden zwei zufällige gigantische Zahlen zurückgegeben.
Bei anderen Funktionen der DLL erfolgt ein Speicherzugriffsfehler oder
er meldet mir Probleme mit dem Stack und bricht ebenfalls ab.
Es hat irgendwie den Anschein, als würde die DLL nicht korrekt
eingebunden.
Ich habe die DLL einfach in der Projektmappe im Projekt unter
"Hinzufügen" -> "Vorhandenes Element hinzufügen" eingebunden.
Hier der Code:
1
Public Class Form1
2
Declare Function auto_set Lib "MPC2810" () As Long
3
Declare Function init_board Lib "MPC2810" () As Long
4
usw.
5
6
' Button click event
7
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
8
Dim a As Long
9
Dim b As Long
10
a = auto_set()
11
b = init_board()
12
MsgBox (a & " " & b)
13
End Sub
14
End Class
Bevor ich mich (wie gesagt: DAU, Beschäftigung mit VB erst seit heute)
komplett verrenne, meine Fragen:
Wie ist der korrekte Weg, eine solche DLL in VB einzubinden und zu
aktivieren, so dass ich deren Funktion nutzen kann?
Ist das Obige ok oder muss ich noch irgendetwas aktivieren?
Gibt es vielleicht Probleme, weil die DLL schon älteren Datums (2009)
ist und VB2010 etwas anderes erwartet?
Wichtig: mir geht es nicht darum, tief in VB einzusteigen - es reicht
mir vollkommen, wenn ich die Karte einfach mit den Befehlen über Basic
ansprechen kann.
Wenn mir jemand, der öfter mal Hardware in VB programmiert, helfen kann,
wäre ich wirklich sehr dankbar :-)
Chris D.
Chris D. schrieb:> Gibt es vielleicht Probleme, weil die DLL schon älteren Datums (2009)> ist und VB2010 etwas anderes erwartet?
Kann eigentlich nicht.
Chris D. schrieb:> Es hat irgendwie den Anschein, als würde die DLL nicht korrekt> eingebunden.
Dann würdest du eine Windows-Fehlermeldung beim Starten deiner .exe
sehen.
Wahrscheinlich hat die DLL eine Initialisierungs-Funktion, die einfach
nur aufgerufen werden muss bevor irgendwelche sonstigen Operationen
damit gemacht werden können... Schau da in Doku der DLL sowie in die
Basic-Datei mit den Funktions-Deklarationen...
Alternativ das ganze mit C probieren ob's da genauso ist ;-)
Der code sieht eigentlich ok aus.
Ich würde zum Test mal ein C programm schreiben was du funktion aufruft.
Normalerweise muss du die DLL auch nicht zum projekt hinzufügen. das
macht VB zur laufzeit. Bein hinzufügen der DLL wird sie nur mit in den
Debug/Relaese ordner kopiert.
Wenn die DLL nicht kompatibel währe (64 vs 32bit) dann könntest du sie
gar nicht laden.
Du Programmiest mit VB 2010 eigentlich aber .net (man könnte dann auch
gleich C# verwenden). Da gibt es die möglichekeit die Callingconvention
anzugeben. Bei VB kann diese anders gewesen sein.
http://msdn.microsoft.com/de-de/library/system.runtime.interopservices.dllimportattribute.callingconvention%28v=vs.80%29.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-4
Dr. Sommer schrieb:> Chris D. schrieb:>> Gibt es vielleicht Probleme, weil die DLL schon älteren Datums (2009)>> ist und VB2010 etwas anderes erwartet?> Kann eigentlich nicht.>> Chris D. schrieb:>> Es hat irgendwie den Anschein, als würde die DLL nicht korrekt>> eingebunden.> Dann würdest du eine Windows-Fehlermeldung beim Starten deiner .exe> sehen.
Nein, da gibt es keine :-)
> Wahrscheinlich hat die DLL eine Initialisierungs-Funktion, die einfach> nur aufgerufen werden muss bevor irgendwelche sonstigen Operationen> damit gemacht werden können... Schau da in Doku der DLL sowie in die> Basic-Datei mit den Funktions-Deklarationen...
In der Doku steht nichts dazu, sondern nur dieses:
"Users can take VB5.0 or higher version for developing motion control
program on the platform of Windows. A simple control program will be
developed according to below steps.
1. Install MPC2810 driver and function library.
2. Startup Visual Basic to create a Project.
3. Copy “MPC2810.dll”and “MPC2810.bas” into Project file.
4. Choose “Add Module” under the menu of “Project”. Add “MPC2810.bas”
into the Project.
5. Calling motion functions in the application."
Dort ist nichts von DLL-Initialisierung angeben. In den Beispielen
starten die auch immer direkt mit auto_set() und init_board().
Meine die mit "Add Module" vielleicht etwas anderes als mein "Hinzufügen
von vorhandenem Element"?
> Alternativ das ganze mit C probieren ob's da genauso ist ;-)
Ich bin froh, dass ich hier Visual Basic laufen habe :-}
Irgendwo muss der Haken sein :-/
Chris D.
Es ist wohl tatsächlich das P/Invoke-Problem gewesen.
Ich habe jetzt die ersten beiden Funktionen von Hand umgeschrieben und
ich erhalte tatsächlich "4 1" für vier Achsen und eine Karte :-)
Habe ich die P/Invoke-problematik richtig verstanden?
Es geht hauptsächlich darum, die Variablentypen von C/C++ auf die
.NET-Typen abzubilden?
Hier mein jetziger Code:
1
Imports System.Runtime.InteropServices
2
3
Public Class Form1
4
5
<DllImport("MPC2810.dll")> _
6
Public Shared Function auto_set() As Int32
7
End Function
8
'Declare Auto Function auto_set Lib "MPC2810" () As Long
9
10
<DllImport("MPC2810.dll")> _
11
Public Shared Function init_board() As Int32
12
End Function
13
'Declare Function init_board Lib "MPC2810" () As Long
14
15
...
Aber es gibt doch sicher eine Möglichkeit, VB zu sagen, dass es alle
(100!) Funktionen automatisch wandelt, oder muss ich jede von hand
umschreiben? :-/
Chris D.
EDIT: @arc: ich bin zu langsam - danke, schaue ich mir mal an. Ja, es
geht um diese DLL.
Wenn das wirklich alles gewesen ist und der Kram morgen zumindest mal
eine Rampe an den Pins erzeugt, dann hast Du einen dicken Stein bei mir
im Brett! :-D
Ansonsten darf ich Dich hoffentlich nochmal nerven ;-)
Chris D. schrieb:> Aber es gibt doch sicher eine Möglichkeit, VB zu sagen, dass es alle> (100!) Funktionen automatisch wandelt, oder muss ich jede von hand> umschreiben? :-/
Ne Fingerübung mit awk?
Chris D. schrieb:> EDIT: @arc: ich bin zu langsam - danke, schaue ich mir mal an. Ja, es> geht um diese DLL.> Wenn das wirklich alles gewesen ist und der Kram morgen zumindest mal> eine Rampe an den Pins erzeugt, dann hast Du einen dicken Stein bei mir> im Brett! :-D
Das sollte reichen, da das anscheinend eine 32-Bit-DLL ist, wenn es auch
noch 64-Bit-Versionen geben sollte, dann muss nur sichergestellt werden,
dass die richtige Version zur Laufzeit geladen wird.
Bei Arrays, Zeigern kann es u.U. etwas aufwendiger sein
http://msdn.microsoft.com/en-us/library/hk9wyw21.aspx
Strings
http://msdn.microsoft.com/en-us/library/s9ts558h.aspx> Ansonsten darf ich Dich hoffentlich nochmal nerven ;-)
Das tun schon die Kunden, die hier mit uralten Sachen angekommen
(Hersteller seit x Jahren nicht mehr existent) und sich wundern warum
einiges nicht "mal eben umgestrickt" werden kann...
Nein, das ist schon so ok - ich hab die Funktionen jetzt automatisiert
gekapselt :-)
Interessant:
Ich hatte Leetro geschrieben bzgl. der Kartenbefehle. Die wollten direkt
die Seriennummer und Fotos der Karte haben ...
Offenbar sind die aus einer chinesischen Maschine ausgebaut worden ...
und siehe da: alle Karten sind Plagiate.
=> null Support
Tjaja, wir müssen sparen, koste es was es wolle :-}
@arc: nochmal danke für den Tipp: die Karte lässt sich jetzt voll
ansteuern.
Und VB macht langsam dann doch Spaß :-)
Chris D.
Hallo Chris D. , als Tipp, schau dir mal FreeBasic an. Ich benutze es
für Unix wie auch für Window$, speziell für embedded Sachen mit USB
Direktzugriff.