Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Probleme mit DLL - Fehler : Zugriffsverletzung

20 views
Skip to first unread message

Ines Otto

unread,
Sep 6, 2001, 4:58:16 AM9/6/01
to
Hallo NG,


ich möchte eine Delphi-DLL (D5 Enterprise) schreiben, mit deren Hilfe von
unserer Datenbank Daten an ein IDL-Programm (Fa. CREASO) übergeben werden sollen.


Mein Problem : Sobald das IDL-Programm die Procedure Int_ueb aufruft antwortet
Dr. Watson! (Ausnahme: Zugriffsverletzung (0xc00000005), Adresse 0x02712dbb).
Die Prozedure Message_ausgeben funktioniert ohne Probleme.


Um die Delphi-DLL zu überprüfen habe ich ein Delphi-Programm geschrieben. Dort
funktionieren beide Prozeduren. Den Code der DLL hänge ich am Ende an.
Kann mir jemand einen Tipp geben?


Mit freundlichen Grüßen
Ines


library DLL_Test;
uses
SysUtils, Dialogs, Classes;


{$R *.RES}


procedure Int_ueb (var a : Integer); stdcall;
begin
ShowMessage ('Wert : ' + IntToStr(a));
end;


procedure Message_ausgeben ;stdcall;
begin
ShowMessage ('Dies ist eine Message ');
end;


exports
Int_ueb,
Message_ausgeben;
begin
end.

--
__________________________________________________________
News suchen, lesen, schreiben mit http://newsgroups.web.de

Alexander Noé

unread,
Sep 6, 2001, 5:15:00 AM9/6/01
to
"Ines Otto" <ines...@web.de> schrieb im Newsbeitrag
news:3b973aaa$1...@netnews.web.de...

> Hallo NG,
>
>
> ich möchte eine Delphi-DLL (D5 Enterprise) schreiben, mit deren Hilfe von
> unserer Datenbank Daten an ein IDL-Programm (Fa. CREASO) übergeben werden
sollen.
>
>
> Mein Problem : Sobald das IDL-Programm die Procedure Int_ueb aufruft
antwortet
> Dr. Watson! (Ausnahme: Zugriffsverletzung (0xc00000005), Adresse
0x02712dbb).
> Die Prozedure Message_ausgeben funktioniert ohne Probleme.

Welche Sprache verwendet das IDL-Programm?

Wenn es C++ ist, dann beachte, daß die Procedur dort als
void _stdcall Int_ueb (int* a)
deklariert sein muß, nicht etwa void _stdcall Int_ueb (int a).


MfG
Alexander


Ines Otto

unread,
Sep 6, 2001, 10:50:00 AM9/6/01
to
Hallo Alexander,


so wie es aussieht, verwendet IDL einen C-Kernel. Näheres war aber von der Firma
nicht zu erfahren. IDL ist eine Software zur Bildbearbeitung und -manipulation.


Dank Deiner Hilfe bin ich aber jetzt ein gutes Stück weitergekommen!
Meine DLL habe ich wie folgt abgeändert:
procedure Int_ueb (argc : Integer; var a : Integer);
stdcall;
begin
if argc = 1 then
begin
ShowMessage ('Wert ' + InttoStr(a));
a := 1234;
end;
end;


Jetzt bekomme ich mit ShowMessage (wahrscheinlich) die Adresse von a angezeigt.
Außerdem wird der geänderte Wert von a nicht im IDL-Programm angezeigt. Auch mit
der Definition von Pointern habe ich nichts erreicht.
Gibt es eine Möglichkeit, die Adresse in einem Integer-Feld als Pointer zu
behandeln? Beim Compilieren erhalte ich die Fehlermeldung: Typunverträglichkeit
Integer und Pointer.
Viele Grüße
Ines

Alexander Noé

unread,
Sep 7, 2001, 11:42:03 AM9/7/01
to
"Ines Otto" <ines...@web.de> schrieb im Newsbeitrag
news:3b978d18$1...@netnews.web.de...

> Hallo Alexander,
>
>
> so wie es aussieht, verwendet IDL einen C-Kernel. Näheres war aber von der
Firma
> nicht zu erfahren. IDL ist eine Software zur Bildbearbeitung
und -manipulation.

> Dank Deiner Hilfe bin ich aber jetzt ein gutes Stück weitergekommen!
> Meine DLL habe ich wie folgt abgeändert:
> procedure Int_ueb (argc : Integer; var a : Integer);
> stdcall;
> begin
> if argc = 1 then
> begin
> ShowMessage ('Wert ' + InttoStr(a));
> a := 1234;
> end;
> end;
>

Du hast ja die Anzahl der Parameter verändert.
Weißt Du genau, daß das IDL-Programm 2 Parameter übergibt ?
So, wie es jetzt hier erscheint, muß Int_ueb wie folgt von dem IDL-Programm
importiert werden:
void Int_ueb (int argc,int *a);

Nun eine _Ahnung_: argc steht normalerweise für argument count, d.h. die
Prozedur könnte mit verschiedenen Anzahlen an Parametern aufgerufen werden.
In diesem Fall mußt Du cdecl statt stdcall verwenden (eine Einschränkung,
die C++ betrifft: AFAIK kann kein C++ - Programm Prozeduren verwenden oder
definierien, deren Parameteranzahl variabel ist, wenn nicht als
Aufrufkonvention cdecl verwendet wird).

Du weißt hoffentlich, daß es egal ist, ob Du
1) var a: Integer und a:=1234 schreibst oder
2) a: PInteger und a^:=1234 schreibst

> Jetzt bekomme ich mit ShowMessage (wahrscheinlich) die Adresse von a
angezeigt.

Soll das heißen, daß var a: integer nur die Adresse des übergebenen Wertes
enthält ?
Falls ja, dann wäre die Definition in C wahrscheinlich nicht, wie oben
angegeben, sondern
void Int_ueb (int argc,int **a);
Hier hat Delphi ein Problem: Eine sauber Unterscheidung von int *a, int **a
oder int ******a ist nicht möglich....

Workaround für int **a:
In diesem Fall könntest Du deine Routine so schreiben:
procedure Int_ueb (argc: Integer; var a: PInteger); stdcall;
...
...
a^:=1234;
...

> Gibt es eine Möglichkeit, die Adresse in einem Integer-Feld als Pointer zu
> behandeln?

So, wie ich es oben gemacht habe, oder:
Du bleibst bei var a: integer und betreibst "type casting":
-> PInteger(a)^:=1234;

Das IDL-Programm erlaubt es ja scheinbar explizit, andere selbstgeschriebene
DLL-Funktionen zu importieren. Folglich muß auch irgendwo erklärt sein, wie
diese Funktionen auszusehen haben und welche Parameter diese zu verwenden
haben, also ein "SDK".
Schau doch mal nach, ob Du sowas findest.
Ich weiß nicht, wie gut Du C++ kannst, denn solche SDKs sind eigentlich
immer in C++ geschrieben. Notfalls einfach fragen.

MfG
Alexander


Ines Otto

unread,
Sep 10, 2001, 5:07:02 AM9/10/01
to
Hallo Alexander,
ich hoffe, ich darf Dich nochmals belästigen.
Von der Fa. CREASO (verantwortlich für IDL) habe ich jetzt ein Beispiel erhalten,
in dem der Aufruf von IDL kommentiert ist. Allerdings ist dieses Beispiel in C++
geschrieben.
Ich arbeite allerdings nur mit Delphi!
Kannst Du mir bitte beim "Übersetzen" des Codes von C++ in Delphi helfen?
Alle meine Versuche sind bisher fehlgeschlagen. Einzig die Übergabe des 1.
Integerfeldes funktioniert in meiner DLL. Alle anderen Werte sind "Hausnummern".


Vielen Dank
Mit freundlichen Grüßen
Ines


#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#ifdef WIN32
__declspec (dllexport) void sum();
#endif


/* CALL_EXTERNAL (Windows)
* C-Beipiel zur Berechnung der Summe aller Array-Elemente
* IDL Aufruf:
* IDL> t=0. & vec=findgen(10)
* IDL> dummy=call_external('c:\wg\sum.dll', 'sum', vec, n_elements(vec), t)
*
* CREASO Training, WG 99
*/


void sum(int argc,void *argv[])
{


int n;
float s,*f, *sum;
char buf[256];


if (argc != 3) {
sprintf(buf, "wrong number of paramaeters");
(void) MessageBox(NULL, buf,NULL, MB_OK);
return FALSE;
}


f= (float *) argv[0];
n= * (int *) argv[1];
sum= (float *) argv[2];


for ( s=0.0; n--;) s += *f++;


*sum=s;

0 new messages