BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Delphi DLL problems

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc
View previous topic :: View next topic  
Author Message
Zebedee
Guest





PostPosted: Fri Feb 27, 2004 8:08 pm    Post subject: Delphi DLL problems Reply with quote



I'm trying to run a Delphi DLL I've written. I'm not sure I've written it
correctly. Can somebody have a look and tell me where I'm going wrong? It's
probably something very simple. This is the calling code:

procedure TAgencyController.Button6Click(Sender: TObject);
var LibHandle :THandle;
begin
LibHandle := LoadLibrary('DatabaseP.dll');
if LibHandle = 0 then ShowMessage('Aaarggghh');
TDataBase.LoadLibrary('');
FreeLibrary(LibHandle);
end;

This is the DLL code.

library DatabaseP;
uses
SysUtils,Classes,DateUtils;

{$R *.res}
// procedure list

Type
TDataBase = class(TObject)
{$ifdef DataBase}
public
Function LoadDataBase(LocationAndName:ShortString):Boolean;
Procedure SaveDataBase(LocationAndName: ShortString);
Procedure AddNew(EmailAddress:ShortString);
Procedure Delete(EmailAddress:ShortString);
Procedure Return(EmailAddress:ShortString; var FirstMailed, FirstReplied,
LastMailed, LastReplied,
FirstCVSent, LastCVSent : ShortString; TimesMailed, TimesReplied,
SillyReplies : Integer; Deleted:Boolean);
Procedure MarkMailed(EmailAddress:ShortString);
Procedure MarkCVSent(EmailAddress:ShortString);
Function HowManyRecords: Integer;
Function HowManyDeleted: Integer;
Function NextDeleted: ShortString;
Function HowManyNotCVd: Integer;
Function HowManyNotReplied: Integer;
Function HowManyNotContacted: Integer;
Function AddressPresent(EmailAddress :ShortString): Boolean;
Function CheckPresentOrDeleted(EmailAddress : ShortString): Boolean;
Function ClearOutDeleted : Integer;
Function IsAddressPresent(EmailAddress: ShortString): boolean;
Function IsAddressDeleted(EmailAddress: ShortString): boolean;
Procedure Rewind;
// return records
Procedure NextFull(EmailAddress:ShortString; var FirstMailed, FirstReplied,
LastMailed, LastReplied,
FirstCVSent, LastCVSent : ShortString; TimesMailed, TimesReplied,
SillyReplies : Integer; Deleted:Boolean);
Function NextNotFirstMailed : ShortString; // returns email address or ''
for no more
Function NextNotFirstCV: ShortString; // returns email address or '' for no
more
Function NextMailedButNotReplied: ShortString; // returns address of people
emailed but who haven't replied
Function NextSevenDaySilence: ShortString;// returns address of people
who've not responded for 7 days.
Function NextFourteenDaySilence: ShortString;// returns address of people
who've not responded for 14 days
Function NextTwentyOneDaySilence: ShortString;// returns address of people
who've not responded for 21 days
Function NextMonthSilence: ShortString;// returns address of people who've
not responded for a month
Function NextTwoMonthSilence: ShortString;// returns address of people
who've not responded for two months
Function NextThreeMonthSilence: ShortString;// returns address of people
who've not responded for two months
Function NextFourMonthSilence: ShortString;// returns address of people
who've not responded for two months
Function NextFiveMonthSilence: ShortString;// returns address of people
who've not responded for two months
Function NextSixMonthSilence: ShortString;// returns address of people
who've not responded for two months
end;

var
DateOfFirstSendingList, DateOfLastSendingList, NumberOfSendingsList,
DateOfFirstReplyList,
DateOfLastReplyList, NumberOfRepliesList, DateOfLastCVSentList,
DateOfFirstCVSentList,
NumberofCVsSentList, NoOfSillyRepliesList, EmailAddressList, DeletedList:
TStringList;
FirstAddressListCounter : integer;

// actual procedures
Function TDataBase.LoadDataBase(LocationAndName:ShortString):boolean;
var
MailingList : Packed Record
DateOfFirstSending : Double;
DateOfLastSending : Double;
NumberOfSendings : integer;
DateOfFirstReply : Double;
DateOfLastReply : Double;
NumberOfReplies : integer;
DateOfLastCVSent : Double;
DateOfFirstCVSent : Double;
NumberofCVsSent : integer;
NoOfSillyReplies : integer;
EmailAddress : ShortString;
RecordDeleted : Boolean;
end;
MyDataFile : TFileStream;
TotalCount : Integer;
DataListCount: Integer;
FileLength : integer;
begin
DateOfFirstSendingList := TStringList.Create;
DateOfLastSendingList := TStringList.Create;
NumberOfSendingsList := TStringList.Create;
DateOfFirstReplyList := TStringList.Create;
DateOfLastReplyList := TStringList.Create;
NumberOfRepliesList := TStringList.Create;
DateOfLastCVSentList := TStringList.Create;
DateOfFirstCVSentList := TStringList.Create;
NumberofCVsSentList := TStringList.Create;
NoOfSillyRepliesList := TStringList.Create;
EmailAddressList := TStringList.Create;
DeletedList := TStringList.Create;
if Not FileExists(LocationAndName) then
begin
Result := False;
Exit;
end;
// so the datafile exists
MyDataFile := TFileStream.Create(LocationAndName,fmOpenRead);
// load the existing database
TotalCount := 0;
DataListCount := 0;
FileLength := MyDataFile.Size;
while DataListCount < FileLength do
begin
TotalCount := TotalCount + 1;
MyDataFile.Position := DataListCount;
MyDataFile.ReadBuffer(MailingList,sizeof(MailingList));
DataListCount := DataListCount + sizeof(MailingList);
EmailAddressList.Add(MailingList.EmailAddress);
NumberOfSendingsList.Add(IntToStr(MailingList.NumberOfSendings));
if MailingList.DateOfLastSending = 0 then DateOfLastSendingList.Add('-')
else

DateOfLastSendingList.Add(DateToStr(ModifiedJulianDateToDateTime(MailingList
..DateOfLastSending)));
if MailingList.DateOfFirstSending = 0 then
DateOfFirstSendingList.Add('-') else

DateOfFirstSendingList.Add(DateToStr(ModifiedJulianDateToDateTime(MailingLis
t.DateOfFirstSending)));
if MailingList.DateOfLastReply = 0 then DateOfLastReplyList.Add('-') else

DateOfLastReplyList.Add(DateToStr(ModifiedJulianDateToDateTime(MailingList.D
ateOfLastReply)));
if MailingList.DateOfFirstReply = 0 then DateOfFirstReplyList.Add('-')
else

DateOfFirstReplyList.Add(DateToStr(ModifiedJulianDateToDateTime(MailingList.
DateOfFirstReply)));
NumberOfRepliesList.Add(IntToStr(MailingList.NumberOfReplies));
if MailingList.DateOfLastCVSent = 0 then DateOfLastCVSentList.Add('-')
else

DateOfLastCVSentList.Add(DateToStr(ModifiedJulianDateToDateTime(MailingList.
DateOfLastCVSent)));
if MailingList.DateOfFirstCVSent = 0 then DateOfFirstCVSentList.Add('-')
else

DateOfFirstCVSentList.Add(DateToStr(ModifiedJulianDateToDateTime(MailingList
..DateOfFirstCVSent)));
NumberofCVsSentList.Add(IntToStr(MailingList.NumberofCVsSent));
NoOfSillyRepliesList.Add(IntToStr(MailingList.NoOfSillyReplies));
DeletedList.Add(BoolToStr(MailingList.RecordDeleted));
end;
MyDataFile.Free;
Result := True;
end;

Procedure TDataBase.SaveDataBase(LocationAndName: ShortString);
var
MailingList : Packed Record
DateOfFirstSending : Double;
DateOfLastSending : Double;
NumberOfSendings : integer;
DateOfFirstReply : Double;
DateOfLastReply : Double;
NumberOfReplies : integer;
DateOfLastCVSent : Double;
DateOfFirstCVSent : Double;
NumberofCVsSent : integer;
NoOfSillyReplies : integer;
EmailAddress : ShortString;
RecordDeleted : Boolean;
end;
MyDataFile : TFileStream;
Count : Integer;
begin
MyDataFile := TFileStream.Create(LocationAndName,fmCreate);
// now go through TStringLists and save data
for Count := 0 to EmailAddressList.Count -1 do
begin
if DateOfFirstSendingList.Strings[Count] = '-' then
MailingList.DateOfFirstSending := 0
else MailingList.DateOfFirstSending :=
DateTimeToModifiedJulianDate(StrToDate(DateOfFirstSendingList.Strings[Count]
));
if DateOfLastSendingList.Strings[Count] = '-' then
MailingList.DateOfLastSending := 0
else MailingList.DateOfLastSending :=
DateTimeToModifiedJulianDate(StrToDate(DateOfLastSendingList.Strings[Count])
);
MailingList.NumberOfSendings :=
StrToInt(NumberOfSendingsList.Strings[Count]);
if DateOfFirstReplyList.Strings[Count] = '-' then
MailingList.DateOfFirstReply := 0
else MailingList.DateOfFirstReply :=
DateTimeToModifiedJulianDate(StrToDate(DateOfFirstReplyList.Strings[Count]))
;
if DateOfLastReplyList.Strings[Count] = '-' then MailingList.DateOfLastReply
:= 0
else MailingList.DateOfLastReply :=
DateTimeToModifiedJulianDate(StrToDate(DateOfLastReplyList.Strings[Count]));
MailingList.NumberOfReplies :=
StrToInt(NumberOfRepliesList.Strings[Count]);
if DateOfFirstCVSentList.Strings[Count] = '-' then
MailingList.DateOfFirstCVSent := 0
else MailingList.DateOfFirstCVSent :=
DateTimeToModifiedJulianDate(StrToDate(DateOfFirstCVSentList.Strings[Count])
);
if DateOfLastCVSentList.Strings[Count] = '-' then
MailingList.DateOfLastCVSent := 0
else MailingList.DateOfLastCVSent :=
DateTimeToModifiedJulianDate(StrToDate(DateOfLastCVSentList.Strings[Count]))
;
MailingList.NumberofCVsSent :=
StrToInt(NumberofCVsSentList.Strings[Count]);
MailingList.NoOfSillyReplies :=
StrToInt(NoOfSillyRepliesList.Strings[Count]);
MailingList.EmailAddress := EmailAddressList.Strings[Count];
MailingList.RecordDeleted := StrToBool(DeletedList.Strings[Count]);
MyDataFile.Write(MailingList,sizeof(MailingList));
end;
MyDataFile.Free;
// now free the memory
DateOfFirstSendingList.Free;
DateOfLastSendingList.Free;
NumberOfSendingsList.Free;
DateOfFirstReplyList.Free;
DateOfLastReplyList.Free;
NumberOfRepliesList.Free;
DateOfLastCVSentList.Free;
DateOfFirstCVSentList.Free;
NumberofCVsSentList.Free;
NoOfSillyRepliesList.Free;
EmailAddressList.Free;
DeletedList.Free;
end;


exports
// procedures to export
DataBase;
{$endif};
end.

--
Yours

Zebedee

(Claiming asylum in an attempt
to escape paying his debts to
Dougal and Florence)



Back to top
Duncan McNiven
Guest





PostPosted: Fri Feb 27, 2004 8:15 pm    Post subject: Re: Delphi DLL problems Reply with quote



On Fri, 27 Feb 2004 20:08:11 -0000, "Zebedee" <abuse (AT) 127 (DOT) 0.0.1> wrote:

Quote:
I'm trying to run a Delphi DLL I've written. I'm not sure I've written it
correctly. Can somebody have a look and tell me where I'm going wrong?

What are we looking FOR? What are the symptoms? What makes you think there is something
wrong? This is a lot of code to look through without a clue what we are looking for.

--
Duncan


Back to top
Zebedee
Guest





PostPosted: Fri Feb 27, 2004 8:58 pm    Post subject: Re: Delphi DLL problems Reply with quote




Well, It's two things.

Firstly, I was expecting the TDataBase to be included in the code so that
when I enter commands in the TForm Event handlers, I would Type DataBase.
and be given a list of available commands within the TDataBase unit.

Basically, it's an inclusion problem. How do I include it?

Also, have I coded the DLL correctly in terms of exporting the gubbins in
such a way as it would perform in code like any other TComponent?
--
Yours

Zebedee

(Claiming asylum in an attempt
to escape paying his debts to
Dougal and Florence)



Back to top
Rob Kennedy
Guest





PostPosted: Fri Feb 27, 2004 10:30 pm    Post subject: Re: Delphi DLL problems Reply with quote

Zebedee wrote:
Quote:
I'm trying to run a Delphi DLL I've written.

You don't happen to be Rhys Sage, do you? Someone by that name was
asking about exporting a "DataBase" from a DLL on the Borland newsgroups
a few hours ago.

Quote:
I'm not sure I've written it
correctly. Can somebody have a look and tell me where I'm going wrong? It's
probably something very simple.

Could you give us a hint? Is there something in particular about your
DLL that isn't working correctly? What is it doing now, and what is it
supposed to be doing instead?

Quote:
This is the calling code:

procedure TAgencyController.Button6Click(Sender: TObject);
var LibHandle :THandle;
begin
LibHandle := LoadLibrary('DatabaseP.dll');
if LibHandle = 0 then ShowMessage('Aaarggghh');

That's really lousy error checking. If LoadLibrary returns 0, call
GetLastError to find out why. You can also call RaiseLastWin32Error
instead, which turns the error code into an easy-to-catch exception.

Quote:
TDataBase.LoadLibrary('');

What's a TDataBase? What does its LoadLibrary method do?

Quote:
FreeLibrary(LibHandle);

After you call FreeLibrary, everything in the DLL should be considered
inaccessible. If your DLL has loaded any files, or if you've created any
objects from code in the DLL, then the DLL *must* remain in memory until
you're finished with those files or objects.

Quote:
library DatabaseP;
uses
SysUtils,Classes,DateUtils;

{$R *.res}
// procedure list

I see no procedure list. I see a class declaration and a handful of
method implementations. The implementations are quite lengthy, and I
suspect that they really have nothing to do with whatever your problem is.

Your first goal should be getting a basic DLL that compiles. Make it
export a function, event if that function doesn't do anything related to
databases yet. Then get so you can load that DLL in your EXE and call
the function. Once you have all that working, *then* worry about making
the DLL manage the database.

Quote:
exports
// procedures to export
DataBase;

Undeclared identifier: DataBase.

Quote:
{$endif};
end.

When the conditional compilation symbol is not defined, the compiler
will interpret your DLL source code like this:

library DatabaseP;
uses
SysUtils,Classes,DateUtils;

{$R *.res}
// procedure list

Type
TDataBase = class(TObject)
end.

Since that isn't even compilable code, is that really what you intended?

Delphi does not allow you to export classes, variables, or methods. The
only things you can export are procedures and functions -- the
standalone kind, not the kind that belong to classes.

--
Rob

Back to top
Duncan McNiven
Guest





PostPosted: Fri Feb 27, 2004 11:12 pm    Post subject: Re: Delphi DLL problems Reply with quote

On Fri, 27 Feb 2004 20:58:30 -0000, "Zebedee" <abuse (AT) 127 (DOT) 0.0.1> wrote:

Quote:

Well, It's two things.

Firstly, I was expecting the TDataBase to be included in the code so that
when I enter commands in the TForm Event handlers, I would Type DataBase.
and be given a list of available commands within the TDataBase unit.

Basically, it's an inclusion problem. How do I include it?

Also, have I coded the DLL correctly in terms of exporting the gubbins in
such a way as it would perform in code like any other TComponent?

I can only endorse what Rob has said. The problem isn't something simple which can quickly
be explained, it is a whole host of things. What it all boils down to, though, is that you
have bitten off more than you can chew. Rob's advice about starting with 1 very simple
function and getting that working in a DLL is a good one. Another technique I think would
be worthwhile for you is to get your functions working properly in an EXE first, before
moving them to a DLL. This will make your debugging much easier, and also when you do move
to the DLL it will only be the DLL stuff you need to worry about.

Incidentally, why are you coding this as a DLL at all?

--
Duncan


Back to top
Zebedee
Guest





PostPosted: Fri Feb 27, 2004 11:21 pm    Post subject: Re: Delphi DLL problems Reply with quote

Why as a DLL? Simply because it gets called by several different programs. I
didn't want to do an extra unit and stick the unit in each program. I
figured a DLL would handle the task better.

I'd wanted to put the different methods into a class structure simply to
make it easier to handle. I gather it's not possible with a Delphi DLL so
I'll have to go back to the old way of doing things and just make the method
names longer, prefixing them all with DataBase.

--
Yours

Zebedee

(Claiming asylum in an attempt
to escape paying his debts to
Dougal and Florence)


"Duncan McNiven" <duncan (AT) mcniven (DOT) net> wrote


Quote:
Incidentally, why are you coding this as a DLL at all?

--
Duncan




Back to top
Duncan McNiven
Guest





PostPosted: Fri Feb 27, 2004 11:56 pm    Post subject: Re: Delphi DLL problems Reply with quote

On Fri, 27 Feb 2004 23:21:26 -0000, "Zebedee" <abuse (AT) 127 (DOT) 0.0.1> wrote:

Quote:
Why as a DLL? Simply because it gets called by several different programs. I
didn't want to do an extra unit and stick the unit in each program. I
figured a DLL would handle the task better.

OK

Quote:
I'd wanted to put the different methods into a class structure simply to
make it easier to handle.

Normally a good idea, but not with a DLL.

Quote:
I gather it's not possible with a Delphi DLL

Not just a Delphi DLL, any DLL. A DLL written in one language can be called by programs
written in another language, so anything which goes over that EXE/DLL boundary should not
be language specific. (Actually it is possible to get around this, but I wouldn't recomend
it).

Quote:
so
I'll have to go back to the old way of doing things and just make the method
names longer, prefixing them all with DataBase.

OK. These things are a matter of style, and long names are normally preferable. In your
code, though, I found the names too long, to the extent that they got in the way of
understanding the code. YMMV.

--
Duncan


Back to top
Rob Kennedy
Guest





PostPosted: Sat Feb 28, 2004 8:07 am    Post subject: Re: Delphi DLL problems Reply with quote

Zebedee wrote:
Quote:
I'd wanted to put the different methods into a class structure simply to
make it easier to handle. I gather it's not possible with a Delphi DLL so
I'll have to go back to the old way of doing things and just make the method
names longer, prefixing them all with DataBase.

You can't export a class, but you can export a function that returns a
class. It's best to have the function return either an interface
reference or a reference to an abstract base class. That simplifies the
class declarations in the EXE.

type
IDatabase = interface
[{guid-goes-here}]
function LoadDatabase(LocationAndName: PChar): Boolean;
procedure SaveDatabase(LocationAndName: PChar);
procedure AddNew(EMailAddress: PChar);
// etc.
end;

function MakeNewDatabase: IDatabase;
begin
Result := TDatabaseImpl.Create as IDatabase;
end;

exports
MakeNewDatabase;

end.

--
Rob

Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.