Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Visual C++ DLL in nutzen - Pointer und Array of Double? (https://www.delphipraxis.net/99651-visual-c-dll-nutzen-pointer-und-array-double.html)

Tumm 15. Sep 2007 11:25


Visual C++ DLL in nutzen - Pointer und Array of Double?
 
Hi

Ich habe schon die Suche benutzt und auch schon ein oder zwei Themen zu dem Thema "C++ DLL in Delphi" gefunden. Dort habe ich "erfahren", dass man um Funktionen aus C++ DLLs in Delphi nutzen zu können, zum Beispiel Funktionen wie stdcall nutzen kann.

Bei Funktionen, wo ich nur Integer und Zeiger zu einer Prozedur übergeben musste hat alles noch schön gefunzt:

Code:
function CasioIO_Open(authorId:Integer;productId:Integer;sendproc:tprocedure;receiveprog:tprocedure):hwnd; stdcall; external thedll;
thedll ist hier eine Variable mit dem Namen der DLL.

Code:
CasioIO_Open(3333,3334,@sendproc,@recprog);
Das funktioniert wie gesagt supi. Bei einer anderen Funktion aus der gleichen DLL muss ich nun aber einen Pointer auf einen Integer bzw. ein Array von Kommazahlen (in der Hilfe zu der DLL steht, dass es ein Array of Double sein muss) übergeben. Wenn ich nun einfach den Integer (in den der Rückgabewert rein soll) übergebe kommt eine Zugriffsverletzung (Als Parameter, es kommt nicht als Rückgabewert!). Wenn ich einen ganz normalen Pointer sende, kommt schon beim Starten der Anwendung eine Zugriffsverletzung wegen external und so.

Mit "cdecl" statt "stdcall" funktioniert es auch nicht :(.


Der Visual C++ Aufruf müsste so lauten (steht in der Hilfe der DLL):
Code:
int WINAPI CasioIO_AfterSend(

int handle,
unsigned char * datatype,
unsigned char * name,
unsigned char * rows,
unsigned char * columns,
double * values,
);
Die Parameterbeschreibung aus der Hilfe:
Zitat:

handle
This is the value which is returned by CasioIO_Open.

datatype
Pointer to a byte where to store the datatype. When the function returns, it will contain 1 for variables, 2 for matrices or 3 for lists.

name
Pointer to a byte where to store the name.

rows
Pointer to a byte where to store the number of rows. When the functions returns, it will contain the number of rows. For variables, this is 1.

columns
Pointer to a byte where to store the number of columns. When the functions returns, it will contain the number of rows. For variables and lists, this is 1.

values
Pointer to an array of doubles (double precision floating points) where to store the values of the variable, lists or matrix. Make sure the array is large enough to contain all the values.

Ich habe es so probiert:

Code:
function CasioIO_Aftersend(handle:INteger;datatype:byte;name:byte;rows:byte;columns:byte;values:array of Double):Integer; cdecl; external thedll;
(Mit ganz "normalen" Integern hat es auch nicht funktioniert)

Tumm

SirThornberry 15. Sep 2007 12:30

Re: Visual C++ DLL in nutzen - Pointer und Array of Double?
 
wenn ein Pointer auf ein Byte erwartet wird darfst du nicht einfach ein normale Byte nehmen sondern eben einen Pointer auf ein Byte. Dudem ist ein dynamisches Array in Delphi etwas ganz anderes als ein Array in C
Delphi-Quellcode:
function CasioIO_Aftersend(handle: Integer; datatype, name, rows, columns: pbyte; values: PDouble):Integer; stdcall; external thedll;
wenn du nicht so fitt in c bist nehm einfach mal einen Header-convertierer der automatisch aus C-Headern Delphi-Header macht. Und dann schau dir an was der Converter gemacht hat um zu verstehen was die einzelnen Dinge in C bedeuten.

oki 15. Sep 2007 12:39

Re: Visual C++ DLL in nutzen - Pointer und Array of Double?
 
Ich denke den Parameter als Var-Parameter zu übergeben sollte auch helfen.
Delphi-Quellcode:
function CasioIO_Aftersend(handle: Integer;
  var datatype : Byte;
  var name : Byte;
  var rows : Byte;
  var columns: Byte;
  var values: Double):Integer; stdcall; external thedll;
Hat den Vorteil, dass man seine "normalen" Variablen nehmen und damit arbeiten kann. Mit dem Zeigergedöns verhaspelt man sich schneller. :wink:
Glaub ich zumindest.

Gruß oki

Apollonius 15. Sep 2007 12:46

Re: Visual C++ DLL in nutzen - Pointer und Array of Double?
 
In Delphi ein dynamisches Array zu nehmen sollte aber funktionieren, denn das ist ein Zeiger auf das erste Element.
Problematisch wird nur, dass man die Größe des Arrays vorher festsetzen muss, aber das muss man bei den Zeigern auch. Und mit var zu arbeiten bringt beim Array meiner Meinung nach kaum etwas.

SirThornberry 15. Sep 2007 12:49

Re: Visual C++ DLL in nutzen - Pointer und Array of Double?
 
beim letzten parameter könnte es zu problemen kommen oder kann man dort das 0te Elemten eines arrays übergeben ohne das der Compiler meckert.
Bei den anderen Parametern ist die Verwendung von var wirklich sinnvoll. Aufpassen muss man erst dann (was hier nicht der vall ist) wenn man einne Parameter übergeben kann aber nicht muss. Dann ist die Verwendung von Pointern (wo man nil) übergeben kann einfacher zu tippen als wenn die Declaration mit var ist.

Ein dynamisches Array ist ein zeiger auf das erste Element? Das wäre mir neu aber ausschließen kann ich es nicht. Trotzdem sollte man darauf nicht aufbauen sonst kommt man in schwierigkeiten wenn das mal bei einer Delphiversion geändert wird. Man sollte immer die Adresse des ersten Array-Elementes übergeben.

DeddyH 15. Sep 2007 12:53

Re: Visual C++ DLL in nutzen - Pointer und Array of Double?
 
Was ich an dieser Implementation echt dämlich finde:
Zitat:

values
Pointer to an array of doubles (double precision floating points) where to store the values of the variable, lists or matrix. Make sure the array is large enough to contain all the values.
Gibt es keine Funktion, mit der man den zu reservierenden Speicher vorher ermitteln kann?

Apollonius 15. Sep 2007 13:18

Re: Visual C++ DLL in nutzen - Pointer und Array of Double?
 
Zitat:

Ein dynamisches Array ist ein zeiger auf das erste Element? Das wäre mir neu aber ausschließen kann ich es nicht.
Man muss sich die Operationen mal im CPU-Fenster anschauen, dann sieht man es deutlich. Und ehrlich gesagt wüsste ich nicht, was sich daran ändern könnte - wie willst du denn dynamische Arrays ohne Zeiger implementieren?

Tumm 15. Sep 2007 13:25

Re: Visual C++ DLL in nutzen - Pointer und Array of Double?
 
Ähh also ich hatte versucht auf ein statisches Array zu zeigen.

Danke für die vielen Tipps :D!

Ich habe
Delphi-Quellcode:
  function CasioIO_Aftersend(handle: Integer;
  var datatype : Byte;
  var name : Byte;
  var rows : Byte;
  var columns: Byte;
  var values: Double):Integer; stdcall; external thedll;
von Oki versucht. Leider kam aber beim Programmstart eine Zugriffsverletzung :(.

[EDIT]Sir Thomberys Vorschlag hat leider auch nicht funktioniert. Allerdings hab ich die Sache mit dem Pointer auf ein Byte bei einer anderen Funktion aus der DLL probiert; dort muss man nur Integer übergeben. Da hat sie (natürlich) gefunzt :D (THX!). Liegt das an diesem Array of Double?[/EDIT]

Tumm 15. Sep 2007 14:35

Re: Visual C++ DLL in nutzen - Pointer und Array of Double?
 
ich habe eben noch weiter probiert. In der DLL gibt es eine zweite Funktion, bei der man auch ein Double-Array übergeben muss. Dort hab ich es mit nur einem Double (statt einem Array) gemacht und es hat gefunzt :D! Aber bei CasioIO_AfterSend geht es immer noch nich :(.

Delphi-Quellcode:
CasioIO_AfterSend(hand,@dtype,@dname,@rows,@columns,@val2[0]);
(geht nich :()
(val2 ist ein Array (Double), die anderen sind bis auf hand alles bytes)

oki 15. Sep 2007 21:47

Re: Visual C++ DLL in nutzen - Pointer und Array of Double?
 
Sorry,
das mit dem Array hatte ich übersehen. Da stimme ich SirThornberry zu. Elemente als Array of Double.
Delphi-Quellcode:
function CasioIO_Aftersend(handle: Integer;
  var datatype : Byte;
  var name : Byte;
  var rows : Byte;
  var columns: Byte;
  values: Pointer):Integer; stdcall; external thedll;
Mit dem Thema dynamisches Array bin ich mir nicht ganz sicher, aber ich glaube es war so:

Statisches Array: (hierbei bin ich mir ziemlich sicher)
Delphi-Quellcode:
var Myhandle: Integer;
  datatype : Byte;
  name : Byte;
  rows : Byte;
  columns: Byte;
  values: Array[0..5] of Double;
begin
  .... // Zuweisung der Werte
  CasioIO_Aftersend(Myhandle, datatype, name, rows, columns, @values[0]);
end;
Dynamisches Array: (hier bin ich mir nicht sicher)
Delphi-Quellcode:
var Myhandle: Integer;
  datatype : Byte;
  name : Byte;
  rows : Byte;
  columns: Byte;
  values: Array of Double;
begin
  SetLength(values, 5);
  .... // Zuweisung der Werte
  CasioIO_Aftersend(Myhandle, datatype, name, rows, columns, values[0]);
end;
Gruß oki


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:34 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz