![]() |
DLL einbinden octopus.dll
Hallo !
Ich habe folgendes Problem : Ich habe einen OctopusUSB ( ![]() Das ist ein Ein/Ausgabe Interface für den Anschluss an USB. Ich habe es mir bestellt, da ich dachte, ich bekomme es auch mit Delphi angesteuert, allerdings komme ich nicht richtig weiter... Dabei ist eine octopus.dll Diese exportiert unter anderem eine Funktion "octopus_init" :
Code:
Dass ich diese mit
/*
* initial octopus handle before use octopus_open */ int octopus_init(struct octopus_context *octopus) { if (octopus == NULL) octopus_error_return(-1,"octopus not valid"); octopus->error_str = NULL; octopus->usb_handle = NULL; return 1; }
Delphi-Quellcode:
aufrufen kann ist klar, aber was mache ich eben mit den Übergabewert "*octopus" ?
function octopus_init(context: octopus_context): integer; external 'octopus.dll';
Das struct octopus_context ist wie folgt definiert :
Code:
Ich habe es versucht mit folgendem record zu übersetzen :
struct octopus_context {
// USB specific /// libusb's usb_dev_handle struct usb_dev_handle *usb_handle; /// String representation of last error char *error_str; };
Delphi-Quellcode:
aber der Inhalt bleibt leer, und sobald ich eine andere Funktion aufrufen möchte, kommt eine exception ...
usb_device_handle = Record
end; octopus_context = record usb_handle : usb_device_handle; error_str : string; end; Ich hoffe mir kann jemand helfen mfg Chris |
Re: DLL einbinden octopus.dll
Hier nochmal ein paar Hintergrundinfos zu dem Teil :
![]() ![]() In C ist es ohne Probleme ansprechbar, allerdings will ich nicht erst ein C-Prog coden, dass ich dann von der Delphi-App fernsteuern lasse ;-) Ich hoffe auf eure Tipps mfg Chris |
Re: DLL einbinden octopus.dll
Falls ich ins falsche Forum gepostet habe, oder einfach zu wenige Informationen wäre ich auch über einen Hinweis dankbar .. :(
|
Re: DLL einbinden octopus.dll
versuch es doch mal so...
Delphi-Quellcode:
function octopus_init(var context: octopus_context): integer; external 'octopus.dll';
|
Re: DLL einbinden octopus.dll
Liste der Anhänge anzeigen (Anzahl: 1)
Es gab wieder denselben fehler, habe den Fehler mal als screenshot angehängt ...
|
Re: DLL einbinden octopus.dll
Zeig doch mal den ganzen Code. Wie rufst du die Funktion denn auf? hast du auch entsprechend Speicher reserviert? Und wie sieht es mit den Aufrufkonventionen aus? Standardmäßig nimmt Delphi, wenn nichts anderes angegeben ist Register. C-DLLs, die auch für andere Programmiersprachen gedacht sind nehmen meist stdcall. Was sagt denn die Dokumentation dazu?
|
Re: DLL einbinden octopus.dll
eventuell sind das alles Zeiger...
Delphi-Quellcode:
type
usb_device_handle = record end; Pusb_device_handle = ^usb_device_handle; octopus_context = record usb_handle : Pusb_device_handle; error_str : pchar; end; Poctopus_context = ^octopus_context;
Delphi-Quellcode:
function octopus_init(context: Poctopus_context): integer; stdcall; external 'octopus.dll';
Delphi-Quellcode:
var context:Poctopus_context;
begin new(context); if octopus_init(context) <> 0 then begin end; end; |
Re: DLL einbinden octopus.dll
Speicher reserviert ? Wohl eher nicht :(
Aber hier mal der Code :
Delphi-Quellcode:
unit octopusU1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Label1: TLabel; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; type usb_device_handle = Record end; octopus_context = record usb_handle : usb_device_handle; error_str : string; end; var Form1: TForm1; oc1 : octopus_context; implementation {$R *.dfm} function octopus_init(var context: octopus_context): integer; external 'octopus.dll'; function octopus_get_hwdesc(var context: octopus_context; desc: Pchar): Pchar; external 'octopus.dll'; function octopus_open(context: octopus_context): integer; external 'octopus.dll'; procedure TForm1.Button1Click(Sender: TObject); var erg : integer; desc1, desc2 : Pchar; begin erg := octopus_init(oc1); desc1 := octopus_get_hwdesc(oc1,desc2); form1.Caption := inttostr(erg); end; end. |
Re: DLL einbinden octopus.dll
Zitat:
|
Re: DLL einbinden octopus.dll
Versuch es mal so...
Delphi-Quellcode:
Aufruf...
type
octopus_context = packed record usb_handle : integer; error_str : pchar; end; Poctopus_context = ^octopus_context; function octopus_init(context: Poctopus_context): integer; stdcall; external 'octopus.dll'; function octopus_open(context: Poctopus_context): integer; stdcall; external 'octopus.dll';
Delphi-Quellcode:
Das Init läuft durch, beim Open erhalte ich die folgende Meldung: "could not found octopus device with pid and vid". Diese Meldung ist ja schonmal vielversprechend, ich habe ja auch kein Gerät. Aber es kommt eben auch keine Access Violation mehr.
var context:Poctopus_context;
begin new(context); try if octopus_init(context) = 0 then raise Exception.Create(context.error_str); if octopus_open(context) < 0 then raise Exception.Create(context.error_str); finally dispose(context); end; end; |
Re: DLL einbinden octopus.dll
Zitat:
|
Re: DLL einbinden octopus.dll
Zitat:
Zitat:
Das ist jetzt wohl wahrscheinlich nicht mehr delphi-spezifisch ... Habe allerdings gerade nochmal in Python an dem selben Rechner das Teil probiert, und da funktioniert es wunderbar ... Aber der Aufruf scheint ja eigentlich zu stimmen, sonst würde ja nicht 1 und der error_str zurückkommen ... Vielleicht stimmt an der dll was nicht .. Ich werd mal weiter forschen ... Falls noch jemand ne Idee hat, lasst es mich wissen :) |
Re: DLL einbinden octopus.dll
Da ich mir auch so ein Teil bestellt habe, verfolge ich das hier auch gespannt. Dein Fehler hat nicht's mehr mit der Octopus.dll zu tun sondern mit der libusb.dll. Habe mir mal den Delphi-Wrapper für die libusb.dll angeschaut und festgestellt,das der usb_handle kein integer ist, sondern ein Pointer. siehe Antwort von Omata.
Delphi-Quellcode:
Den Delphi-Wrapper findest du hier:
usb_device = packed record
next, prev: pusb_device; filename: packed array [0..LIBUSB_PATH_MAX-1] of char; bus: pusb_bus; descriptor: usb_device_descriptor; config: PArray_usb_config_descriptor; dev: pointer; // Darwin support end; usb_bus = packed record next, prev: pusb_bus; dirname: packed array [0..LIBUSB_PATH_MAX-1] of char; devices: pusb_device; location: longint; end; // Version information, Windows specific pusb_version = ^usb_version; usb_version = packed record dllmajor, dllminor, dllmicro, dllnano: integer; drivermajor, driverminor, drivermicro, drivernano: integer; end; pusb_dev_handle = pointer; // struct usb_dev_handle; // typedef struct usb_dev_handle usb_dev_handle; ![]() Evtl. bringt dich das weiter. Wal P.S. Luckie hat geschrieben:
Delphi-Quellcode:
Mit octupus_init wird ja der Pointer geholt, deshalb wird das var wichtig sein und mit octupus_open wird der Pointer wieder der Dll mitgeteilt.
function octopus_init(var context: octopus_context): integer; external 'octopus.dll';
function octopus_get_hwdesc(var context: octopus_context; desc: Pchar): Pchar; external 'octopus.dll'; function octopus_open(context: octopus_context): integer; external 'octopus.dll'; Bin noch nicht der Delphifreak, deshalb berichtigt mich falls ich falsch liege. :-) |
Re: DLL einbinden octopus.dll
Zitat:
Ich habe mal die LibUSB.pas mit in mein Testprogramm aufgenommen, aber leider passiert dabei das selbe ... Chris |
Re: DLL einbinden octopus.dll
Zitat:
|
Re: DLL einbinden octopus.dll
Zitat:
|
Re: DLL einbinden octopus.dll
Zitat:
Meiner Meinung müßte das so gehen:
Delphi-Quellcode:
Mit octopus_init bekommst du den Pointer auf das USB_Handle mitgeteilt, den du bei jedem Zugriff auf das USB-Teil brauchst.type octopus_context = packed record usb_handle : pointer; error_str : pchar; end; Poctopus_context = ^octopus_context; function octopus_init(var context: octopus_context): integer; external 'octopus.dll'; function octopus_open(context: octopus_context): integer; external 'octopus.dll'; var context:Poctopus_context; begin new(context); try if octopus_init(context) = 0 then raise Exception.Create(context.error_str); if octopus_open(context) < 0 then raise Exception.Create(context.error_str); finally dispose(context); end; end; Deshalb am besten auch Global deklarieren. Mit octopus_open übergibst du den Pointer der octopus.dll wieder. Wenn ich keinen falschen Fehler mache müßte das so ungefähr gehen. :? Ich weiß auch nicht genau ob man für den Pointer nicht erst Speicher reservieren muß. Nur mein Delphi ist halt noch nicht so gut. Wal |
Re: DLL einbinden octopus.dll
Zitat:
Hast du dir mal die Init-Routine angesehen?
Code:
Dort siehst du das der übergebene octopus-Zeiger nur dereferenziert wird, das würde schon mal nicht gehen, wenn kein Speicher dafür alloziert wäre. Hier wird also nur der reservierte Speicher initialisiert und kein Speicher reserviert und auch kein Zeiger zurückgeliefert. Es wird nur eine übergebene Speicheradresse initialisiert.
/*
* initial octopus handle before use octopus_open */ int octopus_init(struct octopus_context *octopus) { if (octopus == NULL) octopus_error_return(-1,"octopus not valid"); octopus->error_str = NULL; octopus->usb_handle = NULL; return 1; } |
Re: DLL einbinden octopus.dll
Also der Init läuft ja auch durch, egal ob usb_handle nun Pointer, Pchar oder sonst ein Zeiger ist ...
Aber octopus_open kommt mit error_str "can't set configuration for given usb device" zurück ... In der octopus.c steht :
Code:
und usb_set configuration ist in usb.h folgendermaßen deklariert :
/*
* open octopus with a libusb dev handle */ int octopus_open_dev(struct octopus_context *octopus, struct usb_device *dev) { if (octopus == NULL) octopus_error_return(-1,"octopus handle is wrong or missing"); if (dev == NULL) octopus_error_return(-2,"device handle is wrong or missing"); if (!(octopus->usb_handle = usb_open(dev))) octopus_error_return(-3,"can't open usb device"); if (usb_set_configuration (octopus->usb_handle,dev->config[0].bConfigurationValue) < 0) octopus_error_return(-4,"Ich can't set configuration for given usb device"); if (usb_claim_interface(octopus->usb_handle, 0) < 0) octopus_error_return(-5,"can't claim interface for given usb device"); if (usb_set_altinterface(octopus->usb_handle,0) < 0) octopus_error_return(-6,"can't set altinterface for given usb device"); return 1; }
Code:
int usb_set_configuration(usb_dev_handle *dev, int configuration);
|
Re: DLL einbinden octopus.dll
das struct usb_device sieht übrigens so aus in usb.h:
Code:
struct usb_device {
struct usb_device *next, *prev; char filename[LIBUSB_PATH_MAX]; struct usb_bus *bus; struct usb_device_descriptor descriptor; struct usb_config_descriptor *config; void *dev; /* Darwin support */ unsigned char devnum; unsigned char num_children; struct usb_device **children; }; |
Re: DLL einbinden octopus.dll
@Wal: Der Referenzparameter ist ja nur nebensächlich. Ob der schon bekannte Zeiger wieder zurückgeliefert wird oder nicht ist völlig schnuppe. Wichtig ist nur, dass man selber für das Speicherreservieren sorgen muss.
@multi-man: Deinen Codeauszug habe ich mir auch schon angesehen. Prinzipell sieht das alles schonmal gut aus. Dort werden viele Hürden genommen, wo es schon Fehler hageln könnte. Aber wenn es mit Phyton geht warum sollte das dann nicht auch Delphi gehen? Das ist sehr mysteriös. Weil an der besagten Stelle alle verfügbaren USB-Geräte durchgegangen werden und nach der PID und VID gesucht wird. Da habe ich leider auch grad keinen Einfall mehr. |
Re: DLL einbinden octopus.dll
Zitat:
Ich kann mir nur vorstellen, dass der record octopus_context falsch ist, aber ich kapier einfach nicht, wie der aussehen soll ... in octopus.h ist er ja so beschrieben:
Code:
und in usb.h steht ja
struct octopus_context {
// USB specific /// libusb's usb_dev_handle struct usb_dev_handle *usb_handle; /// String representation of last error char *error_str; };
Code:
Wobei ich sagen muss dass ich die deklaration in usb.h garnicht verstehe, dafür ist mein c zu schlecht ...
struct usb_dev_handle;
typedef struct usb_dev_handle usb_dev_handle; lg |
Re: DLL einbinden octopus.dll
Zitat:
Delphi-Quellcode:
Wal
pusb_dev_handle = pointer; // struct usb_dev_handle;
// typedef struct usb_dev_handle usb_dev_handle; |
Re: DLL einbinden octopus.dll
Zitat:
Wenn der usb_handle ein Pointer ist, dann war meine Annahme einen Integer zunehmen ja nicht so abwegig. Das ist die gleiche Größe im Speicher und ob der nun aus Delphi heraus dereferenziert werden kann oder nicht ist doch egal, weil der Zugriff doch sowieso nur durch die Dll erfolgt. Damit reicht es doch den Speicher dafür bereit zustellen und genau das ist hier bis jetzt passiert. |
Re: DLL einbinden octopus.dll
Habe heute das OctopusCan bekommen, bei mir funzt das Ganze ohne Fehlermeldung mit dem Code von Omata.
Er übergibt mir bei Init und Open jeweils 1. Wal |
Re: DLL einbinden octopus.dll
@Wal:
Kannst Du mal den kompletten Code posten, vielleicht hab ich ja irgendwie nen Fehler gemacht .. Welche LibUSB hast du denn auf dem PC ? Welche Firmware auf dem octopus ? Ich bekomme bei open und init auch ne 1 zurück, aber im error_str steht dann bei mir "can't set configuration for given usb device" und beim versuch einen Pin zu schalten, kommt "communication error" in den error_str LG |
Re: DLL einbinden octopus.dll
Ich nutze den SVN. Habe aber auch den Fehler, das ich kein Pin schalten kann. Der Fehler wird im Octopus-Forum beschrieben, aber die alternativen Firmware funzt bei mir auch nicht.
Wal |
Re: DLL einbinden octopus.dll
hmm, ja ist schon merkwürdig ...
Also mit Python funzt es es ja bei mir wunderbar, habe auch schon probiert, mit python4delphi den code im wrapper auszuführen, aber auch dabei kommt eine exception raus ... |
Re: DLL einbinden octopus.dll
Habe hier ein simples Programm geschrieben um eine Led anzusteuern.
Werde mal versuchen eine Compo daraus zu machen. Hauptsache man sieht mal was. Nehme direkt die LibUSB und ohne die Octopus.dll. Wal Neue Version unten. |
Re: DLL einbinden octopus.dll
Liste der Anhänge anzeigen (Anzahl: 1)
Eine verbesserte Version, der demo.c im Ordner Demos nachempfunden.
Wal |
Re: DLL einbinden octopus.dll
Liste der Anhänge anzeigen (Anzahl: 1)
So die Delphi-Compo ist soweit einsatzbereit, es laufen alle Pin und Port Befehle.
Der Rest ist auch kein Hexenwerk mehr. Wal |
Re: DLL einbinden octopus.dll
Danke Wal für die super Arbeit !
Du hast ja einen OctopusCAN, kann also sein dass es daran liegt, aber bei mir geht das mit den Pins setzen ganz gut, nur mit den Ports geht es nicht ... Ich hab mir die Funktionen angeguckt, und kann es mir nicht recht erklären, da die Funktionen für die Ports ja genauso sind wie die für die Pins... Könnte es an der Firmware liegen ? LG |
Re: DLL einbinden octopus.dll
Zitat:
ich nutze die Firmware vom SVN. Die Sourcen der Firmware ist bei beiden gleich, es wird nur ein Schalter gesetzt. Auszug aus dem Makefile:
Delphi-Quellcode:
Im SVN gibt's:
# mth 2004/09
# Differences from WinAVR 20040720 sample: # - DEPFLAGS according to Eric Weddingtion's fix (avrfreaks/gcc-forum) # - F_OSC Define in CFLAGS and AFLAGS # MCU name MCU = atmega128 #MCU = at90can128 # Main Oscillator Frequency # This is only used to define F_OSC in all assembler and c-sources. F_OSC = 16000000 # Output format. (can be srec, ihex, binary) FORMAT = ihex # Target file name (without extension). TARGET = main Main.hex 38KB Octopus.hex 37KB Octopus_can.hex 37KB <--meine evtl. gib's auch 3 Octopus-Versionen Ich denke du brauchst die Octopus.hex und hast z.Z. die Main.hex. Wal Nachtrag: Als USB-Treiber nutze ich den neusten von der LibUSB-Seite "libusb-win32-filter-bin-0.1.12.1.exe". Habe hier auch noch ein Video gemacht für dich, damit du siehst wie es bei dir aussehen könnte. :cheer: ![]() |
Re: DLL einbinden octopus.dll
Ich habe mir nochmal die aktuelle Firmware aus dem SVN gezogen. Hab mich da mal in die Sourcen eingelesen und ich glaube ja fast dass es die port-funktionen noch gar nicht gibt ...
in der io.c z.B. steht :
Code:
Welche Firmware hast du denn ?
uint8_t io_set_port_direction_out(uint8_t port,uint8_t mask)
{ /* TODO switch (port) { case 1: DDRB = mask; break; case 2: DDRC = mask; break; // PC7 = /CS (output) - do we need to mask this ? case 3: DDRD = mask; break; case 4: DDRE = mask; break; // PE4 = INT4 (input) - do we need to mask this ? case 5: DDRF = mask; break; default: return RSP_UNKOWN_PIN; } */ return RSP_OK; } Ich habe sie heute mit "svn export http://octopususb.googlecode.com/svn/trunk" geholt ... Ist das falsch ? |
Re: DLL einbinden octopus.dll
Wie oben beschrieben, die octopus_can.hex aus dem Firmware-Ordner.
Die io.c sieht bei mir auch so aus. Wal Nachtrag: Die octopus_can.hex aus dem SVN und die aus der Version octopususb-0.3 sind gleich, eben getestet. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:35 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz