Forum: PC-Programmierung Visual Basic 2010 und Fremd-DLL für CNC-PCI-Karte


von Chris D. (myfairtux) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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 ;-)

von Arc N. (arc)


Lesenswert?

DllImport/PInvoke wenn es eine native DLL ist
http://msdn.microsoft.com/en-us/library/aa719104(v=vs.71).aspx

von Peter II (Gast)


Lesenswert?

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

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

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.

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Arc Net schrieb:
> DllImport/PInvoke wenn es eine native DLL ist
> http://msdn.microsoft.com/en-us/library/aa719104(v=vs.71).aspx

Danke, lese ich mir direkt mal durch!

Bei dem einen Stack-Fehler stand auch irgendetwas von PInvoke drin.

Chris D.

von Arc N. (arc)


Lesenswert?

Chris D. schrieb:
> Arc Net schrieb:
>> DllImport/PInvoke wenn es eine native DLL ist
>> http://msdn.microsoft.com/en-us/library/aa719104(v=vs.71).aspx
>
> Danke, lese ich mir direkt mal durch!
>
> Bei dem einen Stack-Fehler stand auch irgendetwas von PInvoke drin.
>
> Chris D.

Wenn das diese
http://www.leetro.com/english/down/MPC2810%20Software%20Manual-v1.0.pdf
ist, dann ist das eine native DLL.
Z.T. lässt sich das automatisieren:
http://clrinterop.codeplex.com/releases/view/14120

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

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 ;-)

von Sven P. (Gast)


Lesenswert?

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?

von Arc N. (arc)


Lesenswert?

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

von Dr. Sommer (Gast)


Lesenswert?

Alternativ einfach ein natives nicht-.NET VB Projekt erstellen... ?

von Arc N. (arc)


Lesenswert?

Dr. Sommer schrieb:
> Alternativ einfach ein natives nicht-.NET VB Projekt erstellen... ?

Also zurück zu VB6?

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

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.

von Chris (Gast)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.