Link to home
Start Free TrialLog in
Avatar of clopez
clopez

asked on

Access violation on DLL

The next code is placed on a DLL and loaded using GetProcAddress from de DLL (there are similar DLLs with the same procedures in them), and runned from a thread,

procedure PageProducer(var FQuery: TQuery; const SourcePath, OutPath, FileName, FIndex: shortstring);
var pp: TDataSetPageProducer;
   f: TextFile;
   sfilename: string;
   sfileext: string;
   FullFileName:string;
   FS:TFileStream;
   s:String;
begin
   pp := TDataSetPageProducer.Create(nil);
   pp.Dataset := FQuery;
   pp.HTMLFile := SourcePath + '\' + FileName;
   FQuery.First;
   SFileName := FileName;
   SFileExt := ExtractFileExt(SFileName);
   SFileName := Copy(SFileName, 1, Length(SFileName) - Length(SFileExt));
   while not FQuery.EOF do
   begin
      FullFileName:=OutPath + '\' + SFileName + FQuery.FieldByName(FIndex).AsString + SFileExt;
>>>      s:=pp.Content;
      FS:=TFileStream.Create(FullFileName,fmCreate);
      FS.Write(s,Length(s));
      FS.Free;
      FQuery.Next;
   end;
   pp.Free;
end;

The line marked with an >>> raises an error of access each time its executed.  If I comment the line and empty file is generated. Any ideas.

Comments:

1.-The procedure must be in a DLL
2.-Must be called from a thread.
3.-In the thread is called within a Syncronize (I first tryed not to).

Avatar of clopez
clopez

ASKER

The code worked ok when it was in the Thread, but started working wrong when moved to the DLL
Are you already used SHAREMEM at the DLL...????????????

uses
   SHAREMEM, Windows, Sysutils.... etc etc etc
You could try using runtime packages (go to Project|Options, packages tab and check the build with runtime packages checkbox. Do this for both the application and the DLL.

Cheers,

Raymond.
I agree with garizpe, you probably need to add ShareMem to both the application and dll. This has one side-effect, though: You have to distribute Borland's "borlndmm.dll" with your application. If you don't like that, you might want to look at my (free) unit "madShareMem", which has the same functionality, but without needing this "borlndmm.dll". On my homepage there are also some infos about when and why you have to use ShareMem and so on...

Regards, Madshi.

www.madshi.net
Avatar of clopez

ASKER

ShareMem doesn't work.  I still get the access message error.

I even changed the code for writing the file to:

      AssignFile(f,FullFileName);
      ReWrite(f);
      Write(f,pp.Content);
      CloseFile(f);

and got an Access violation at address 410046D7 in module 'borlndmm.dll'. Read of address 7469743C

For sure the problem comes when trying to read the Content property;
Avatar of Wim ten Brink
ShareMem should not be required for this routine. It passes shortstrings which don't require special memory management and the TQuery Object isn't freed or destroyed in this routine.
But I would have defined the FQuery parameter as TDataset, so the DLL could be a big smaller in size. It doesn't require the BDE and the unit DBTables in that case... So:
procedure PageProducer(var FQuery: TDataset; const SourcePath, OutPath, FileName, FIndex: shortstring);

That´s right Workshop_Alex, TDataset is the best option
I'm no expert in DB questions. But I find it interesting that your access violation occurs in "borlndmm.dll" (which contains nothing but the memory manager for shared memory). This indicated IMO, that the memory allocation/freeing could really be the problem. Have you placed ShareMem at the right position? It must be the *very* first imported unit in your *project* file (*.dpr). It's not enough to import it somewhere in your project file, or in one of your units.
Avatar of clopez

ASKER

Updates,

1.- When I placed the sharemem it was placed in first position.

2.- I will test the dataset solutin, thanl for the comment.

3.- Radler, Thanks for the session advise. I will try it.
Avatar of clopez

ASKER

Solution fully operative.  Remove de FQuery and send the params for building the query as shortstrings.  No need for ShareMem
Well, I could have suggested that... But I just assumed you needed more information than just the SQL Query... (And the others probably did too...)
What about the TDataset option? Have you tested that?
Avatar of clopez

ASKER

Sorry for the missunderstanding,

I need the TQuery/TDataset option,  otherwise I have to run the same query many times and the program will load the machine.

About the Dataset option, is still in test period, but I still get the Access violation at address 04731F17 in module 'htmlpage.pdi'. Read of address 00000001 error.

I needed to keep working with the rest of the developement somehow.

What we need to come up with is why does the TDatasetPageProducer abends whe it trys to access the Query if its not created inside de DLL.
Are you running multiple threads (at the same time) here?
Avatar of clopez

ASKER

The sistem is configured to run up to 10 threads at the same time.  The threads can be this type or other.  Usually a thread only takes a few seconds (4-5) to end.
I think you can't use a single TQuery in 10 threads.....
Avatar of clopez

ASKER

Can you explain futher Epsylon, just for knowing...
I think that using the same TQuery object in multiple threads won't work....
Hi clopez,

Resuming what was previuosly said, you can put - You should decide - a CriticalSession before use this query, or create a set of TQuerys following the rules:
- A TSession and a TDatabase by thread ( TQuery linked )
- AutoSesionName = true
- Keep Connections = true
- TDatabase.Connected=False
- KeepConnected = true
- SessionName = 'The TSession.SessionName provided by BDE', must be taked by code.

using DllEntryPoint and the reason DLL_THREAD_ATTACH/DLL_THREAD_DETTACH

A pratical way is create a List of DataModules( all elements are inside  ), and to each dll thread load create an association by the ThreadID, like
i:=TStrngList.IndexOf(  IntToStr( ThreadID ) )
DataModule:=TString.Objects[i];
......

The start poin is this way. If any question tell us.

T++ , Radler.
clopez:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
Wow, Its been a long time since this comment have been visited!

clopez,
No comment has been added lately (1 days), so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area for this question:

RECOMMENDATION: PAQ/No Refund

-- Please DO NOT accept this comment as an answer ! --

Thanks,

knightmad
EE Cleanup Volunteer

Remember you (all) can object this recommendation if you disagree, just leave a post here explaining why are you objecting and what should be done instead.
Within 7 days probably this thread will be closed, so, hurry up! : )
ASKER CERTIFIED SOLUTION
Avatar of YensidMod
YensidMod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial