function scauto_connect(Id: string; Server: string; Events: string; Users: string) : Integer; function scauto_query(Id: string; Start: string; Opt: string; var Event: scauto_event) : Integer;
type {* This is what the DLL really wants to see *} real_scauto_event = packed record evfields: PAnsiChar; evtype: array[0..16] of AnsiChar; evtime: array[0..17] of AnsiChar; evsysseq: array[0..32] of AnsiChar; evusrseq: array [0..32] of AnsiChar; evsysopt: array [0..24] of AnsiChar; evuser: array [0..24] of AnsiChar; evpswd: array [0..24] of AnsiChar; evsepchar: AnsiChar; end;
function real_scauto_connect(Id: PChar; Server: PChar; Events: PChar; Users: PChar) : Integer; stdcall; external \'scauto.dll\' name \'scauto_connect\';
function real_scauto_query(Id: PChar; Start: PChar; Opt: PChar; var Event: real_scauto_event) : Integer; stdcall; external \'scauto.dll\' name \'scauto_query\';
function scauto_connect(Id: string; Server: string; Events: string; Users: string) : Integer; begin scauto_connect := real_scauto_connect(PChar(Id), PChar(Server), PChar(Events), PChar(Users)); end;
function scauto_query(Id: string; Start: string; Opt: string; var Event: scauto_event) : Integer; var real_ev : real_scauto_event; status : Integer; begin status := real_scauto_query(PChar(Id), PChar(Start), PChar(Opt), real_ev); if status = 0 then real_to_fake(real_ev, Event); scauto_query := status; end;
Mit program fejler HVER gang ved udførelsen af scauto_query := status; i funtionen scauto_query
Hvad overser jeg?
ps jeg har kun pillet det ud fra min kode som jeg mener er relevant.
prøv at lave dummy function og procedure. Altså en function der bare smider noget tilbage - her mener jeg man skal stdcall eller noget i den retning, ellers Access Violation\'ereenne den...! Og prøv en procedure der bare siger \'Godddag!\', med ShowMessage();
for at se om den stadig siger Access Violation - for hvis den gør så mangler du noget bindeled af en art. Jeg brugte selv meget tid på at få vanskelige functions til at køre i DLL\'er!
Jeg har ikke meget forstand på dll\'s men jeg gætter på at det her er et IP nr \'10.0.0.100.12690\', og hvis det er så er det ikke validt, et IP nr må maks være 255 på de forskellige pladser
Du har gættet rigtigt, det er et ip nummer, men det sidste tal er skam også tilladt det er nemlig et portnummer og den eksterne dll forventer ip nummeret i det format. Så det er ikke det der er fejlen.
dkklein >> så må du trace... det selvfølgelig lidt svært via en dll...
kan du køre koden fra selve programmet (exe) uden nogle fejl???
morten_s >> EAccessViolation er den handling der udføres på en Access Violation.
Delphi Hjælp:
EAccessViolation is the exception class for invalid memory access errors
Unit
SysUtils
Description
EAccessViolation is raised when an application
Dereferences a nil pointer. Writes to memory reserved for executable code. Attempts to access a memory address for which there is no virtual memory allocated to the application.
Run-time exception information is saved in fields provided by EExternal.
Note: Applications should not raise EAccessViolation directly, but should instead rely on the runtime to raise this exception.
Det er ikke ip/port nummer der er problemet. Jeg kunne også have skrevet \'servernavn.portnummer\' ex \'minserver.12690\' ville være det samme. Et standard ip nummer består af 4 blokke tal mellem 0 og 255, hvad der måtte følge efter tolkes af den pågældende routine som et portnummer altså er det formatteret korrekt.
så er der noget helt galt, med sendingen. prøv ud result := et-eller-andet, for at se om den stadig gør det, hvis ikke så prøv at smide result := på igen og kald functionen således:
function scauto_query(Id: string; Start: string; Opt: string; var Event: scauto_event) : Integer; stdcall; var real_ev : real_scauto_event; status : Integer; begin status := real_scauto_query(PChar(Id), PChar(Start), PChar(Opt), real_ev); if status = 0 then real_to_fake(real_ev, Event); scauto_query := status; end;
hvis den stadig melder fejl, når du har fjernet result := så er det noget længere oppe i funcktionen der kuldre. Måske real_to_fake(), da den befinder sig i exefilen - eller har jeg misforstået noget...?
Det gjorde ingen forskel. Men nu har jeg konstateret at det må være returneringen af result den er gal med og altså heller ikke real_to_fake.
Når koden ser således ud:
function scauto_query(Id: string; Start: string; Opt: string; var Event: scauto_event) : Integer; var real_ev : real_scauto_event; status : Integer; begin status := real_scauto_query(PChar(Id), PChar(Start), PChar(Opt), real_ev); if status = 0 then real_to_fake(real_ev, Event); result := status; end;
eller
function scauto_query(Id: string; Start: string; Opt: string; var Event: scauto_event) : Integer; var real_ev : real_scauto_event; status : Integer; begin status := real_scauto_query(PChar(Id), PChar(Start), PChar(Opt), real_ev); if status = 0 then real_to_fake(real_ev, Event); scauto_query := status; end;
så fejler den, ser den derimod således ud
function scauto_query(Id: string; Start: string; Opt: string; var Event: scauto_event) : Integer; var real_ev : real_scauto_event; status : Integer; begin status := real_scauto_query(PChar(Id), PChar(Start), PChar(Opt), real_ev); if status = 0 then real_to_fake(real_ev, Event); end;
Så fejler den ikke! Men det går bare ikke for jeg skal bruge retur koden til det videre program forløb.
Jeg fik det lige til at virke ved at ændre functions kaldet til at status overgives som parameter i selv kaldet:
function scauto_query(Id: string; Start: string; Opt: string; var Event: scauto_event; var testtkj: Integer) : Integer; var real_ev : real_scauto_event; status : Integer; begin status := real_scauto_query(PChar(Id), PChar(Start), PChar(Opt), real_ev); if status = 0 then real_to_fake(real_ev, Event); testtkj:=status; (* scauto_query := status; result := 0; *) end;
Altså som variablen testtkj
Men så kørte jeg programmet 4-6 gange og fejlen var tilbage igen!!! Det fejler nu i testtkj:=status så jeg tror du har ret i det trick, men så er spørgsmålet hvor jeg finder det henne. Jeg har kigget lidt i bogen Mastering Deplhi 6 men ikke fundet så meget, har du en ide til hvor i delphi manualen jeg kan finde noget. Opslag i index på dll, external eller dynamic link libraries giver intet.
nu sidder jeg som sagt i et forkert OP (WinME) til at starte Delphi og hjælpe dig de vej. Men hvis du åbner den nørdede Delphi Hjælp og søger på noget i retingen af dll, dynamik library, calling functions etc. så kan den give dig en helt masse gode forslag. Jeg vender lige tilbage med noget kode som jeg kom i tanke om netop nu...
prøv lige at se hvad Delphi skriver til en når man laver en ny DLL:
Important note about DLL memory management: ShareMem must be the first unit in your library\'s USES clause AND your project\'s (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters.
har du overværet at putte ShareMem ind i dit exe-projekt??
post en ny, bare med et andet navn, og link her til... men jeg er bange for den er svær, det er jo rent gætværk, for hverken dig, mig eller nogen anden på eksperten.dk kan vide hvad der står skrevet i den DLL... medmindre man har source eller er en dygtig hacker :)´
Mit problem er løst. Det viste sig at være scauto_event recorden der havde forkerte længder angivet på strings.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.