 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Martijn Tonies Guest
|
Posted: Wed Apr 11, 2007 4:30 pm Post subject: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
Hi,
I'm working on making our driver DBX3 compatible. So far so good, I'd say.
D2006 loads the driver without problems and displays data.
However, when trying to use the driver with D2007, the DBXDynalink thingy
tries to load it and the driver raises an error.
It happens here:
function TDBXDynalinkDriverCommonLoader.Load(DriverDef: TDBXDriverDef):
TDBXDriver;
....
ErrorResult := FMethodTable.FDBXLoader_GetDriver(Count, Names,
Values,
TDBXWideStringBuilder(ErrorMessageBuilder),
FDriverHandle);
....
I have no idea whatsoever what's going on. I cannot debug the driver
from the D2007 IDE, cause it cannot compile it (due to missing dbExpress
interfaces, as those are deprecated).
How are we supposed to compile DBX3 drivers with D2007??
Got any clue with regard to the driver?
--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com |
|
| Back to top |
|
 |
Martijn Tonies Guest
|
Posted: Wed Apr 11, 2007 7:13 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
| Quote: | I have no idea whatsoever what's going on. I cannot debug the driver
from the D2007 IDE, cause it cannot compile it (due to missing
dbExpress interfaces, as those are deprecated).
You should be able to use the D2006 PAS or DCU files for these in
D2007.
|
Right, that worked.
It fails here:
ISQLDriver(Obj) := DriverInstance;
Where "Obj" is defined as:
function getSQLDriverFB(sVendorLib : PChar; sResourceFile : PChar; out Obj):
SQLResult; stdcall;
This works fine in D2006, but somehow fails inside the dynalink loader...
--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com |
|
| Back to top |
|
 |
Martijn Tonies Guest
|
Posted: Wed Apr 11, 2007 7:34 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
| Quote: | function getSQLDriverFB(sVendorLib : PChar; sResourceFile : PChar;
out Obj): SQLResult; stdcall;
Is this CodeGear's code or yours? I don't know much about dbExpress
innards, but returning an interface as an untyped argument is odd to
say the least.
|
That is my function.
Here's how Borland (BDS 2006 and before) defined the "get driver func":
type
TGetDriverFunc = function(SVendorLib, SResourceFile: PChar; out Obj):
SQLResult; stdcall;
So, this is what I was doing. And it worked in D6, D7 and D2006... :-/
The dbExpress interfaces don't have GUIDs, so "Supports" or "as" don't work.
--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com |
|
| Back to top |
|
 |
Craig Stuntz [TeamB] Guest
|
Posted: Wed Apr 11, 2007 7:44 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
Martijn Tonies wrote:
| Quote: | I have no idea whatsoever what's going on. I cannot debug the driver
from the D2007 IDE, cause it cannot compile it (due to missing
dbExpress interfaces, as those are deprecated).
|
You should be able to use the D2006 PAS or DCU files for these in
D2007.
--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
Everything You Need to Know About InterBase Character Sets:
http://blogs.teamb.com/craigstuntz/articles/403.aspx |
|
| Back to top |
|
 |
Craig Stuntz [TeamB] Guest
|
Posted: Wed Apr 11, 2007 8:28 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
Martijn Tonies wrote:
| Quote: | function getSQLDriverFB(sVendorLib : PChar; sResourceFile : PChar;
out Obj): SQLResult; stdcall;
|
Is this CodeGear's code or yours? I don't know much about dbExpress
innards, but returning an interface as an untyped argument is odd to
say the least.
--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
Everything You Need to Know About InterBase Character Sets:
http://blogs.teamb.com/craigstuntz/articles/403.aspx |
|
| Back to top |
|
 |
Martijn Tonies Guest
|
Posted: Wed Apr 11, 2007 8:30 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
| Quote: | So, this is what I was doing. And it worked in D6, D7 and D2006... :-/
The dbExpress interfaces don't have GUIDs, so "Supports" or "as"
don't work.
Right, you'd have to do the hard cast. That's not really the question,
though; it's the untyped argument which I found odd. But yes you'd have
to conform to the type of TGetDriverFunc.
Is it this assignment:
ISQLDriver(Obj) := DriverInstance;
...itself which raises the AV? If so then it may be failing in trying
to dereference DriverInstance. You can test this with a dummy
assignment to a typed variable:
var
Foo: ISQLDriver;
begin
[...]
Foo := DriverInstance; // does it fail here?
|
This works.
| Quote: | ISQLDriver(Obj) := DriverInstance; // or only here?
|
This fails with the AV (read of address 00000001A).
--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com |
|
| Back to top |
|
 |
Craig Stuntz [TeamB] Guest
|
Posted: Wed Apr 11, 2007 9:10 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
Martijn Tonies wrote:
| Quote: | So, this is what I was doing. And it worked in D6, D7 and D2006... :-/
The dbExpress interfaces don't have GUIDs, so "Supports" or "as"
don't work.
|
Right, you'd have to do the hard cast. That's not really the question,
though; it's the untyped argument which I found odd. But yes you'd have
to conform to the type of TGetDriverFunc.
Is it this assignment:
ISQLDriver(Obj) := DriverInstance;
...itself which raises the AV? If so then it may be failing in trying
to dereference DriverInstance. You can test this with a dummy
assignment to a typed variable:
var
Foo: ISQLDriver;
begin
[...]
Foo := DriverInstance; // does it fail here?
ISQLDriver(Obj) := DriverInstance; // or only here?
-Craig
--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
Everything You Need to Know About InterBase Character Sets:
http://blogs.teamb.com/craigstuntz/articles/403.aspx |
|
| Back to top |
|
 |
Martijn Tonies Guest
|
Posted: Wed Apr 11, 2007 9:18 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
| Quote: | ISQLDriver(Obj) := DriverInstance; // or only here?
This fails with the AV (read of address 00000001A).
Hmmm... I'd suggest rebuilding with debug DCUs and trace into the
assignment to see if you can get any closer to the error.
|
procedure _IntfCopy(var Dest: IInterface; const Source: IInterface);
{$IFDEF PUREPASCAL}
var
P: Pointer;
begin
P := Pointer(Dest);
if Source <> nil then
Source._AddRef;
Pointer(Dest) := Pointer(Source);
if P <> nil then
IInterface(P)._Release;
end;
{$ELSE}
asm
{
The most common case is the single assignment of a non-nil interface
to a nil interface. So we streamline that case here. After this,
we give essentially equal weight to other outcomes.
The semantics are: The source intf must be addrefed *before* it
is assigned to the destination. The old intf must be released
after the new intf is addrefed to support self assignment (I := I).
Either intf can be nil. The first requirement is really to make an
error case function a little better, and to improve the behaviour
of multithreaded applications - if the addref throws an exception,
you don't want the interface to have been assigned here, and if the
assignment is made to a global and another thread references it,
again you don't want the intf to be available until the reference
count is bumped.
}
TEST EDX,EDX // is source nil?
JE @@NilSource
PUSH EDX // save source
PUSH EAX // save dest
MOV EAX,[EDX] // get source vmt
PUSH EDX // source as arg
CALL DWORD PTR [EAX] + VMTOFFSET IInterface._AddRef
POP EAX // retrieve dest
MOV ECX, [EAX] // get current value
POP [EAX] // set dest in place
TEST ECX, ECX // is current value nil?
JNE @@ReleaseDest // no, release it
It jumps to ReleaseDest (current value <> nil).
RET // most common case, we return here
@@ReleaseDest:
MOV EAX,[ECX] // get current value vmt
PUSH ECX // current value as arg
CALL DWORD PTR [EAX] + VMTOFFSET IInterface._Release
Here, it fails with the AV.
Would this mean the "Out" parameter isn't NIL? Even if so, why should it?
Isn't it "Out" only?
RET
--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com |
|
| Back to top |
|
 |
Martijn Tonies Guest
|
Posted: Wed Apr 11, 2007 9:27 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
| Quote: | ISQLDriver(Obj) := DriverInstance; // or only here?
This fails with the AV (read of address 00000001A).
|
This seems to work:
Pointer(Obj) := nil;
ISQLDriver(Obj) := DriverInstance;
--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com |
|
| Back to top |
|
 |
Martijn Tonies Guest
|
Posted: Wed Apr 11, 2007 9:45 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
| Quote: | Would this mean the "Out" parameter isn't NIL? Even if so, why should
it? Isn't it "Out" only?
Yes and no. "out" is the same as "var". "out" params *should* be used
as out only, but the compiler doesn't enforce it.
Yes, it means the out is non-nil. Calling _Release on a non-nil and
not-pointing-to-any-allocated-object-implementing-an-interface can
indeed raise an AV, since _Release is virtual. Your workaround seems
correct to me.
|
So I thought.
I'm a bit puzzled as why this used to work before though.
All this being said, I'm now getting another weird error in the
DynalinkNative when FDBXConnection_GetIsolation is being
used.
Off to the debugger.
--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com |
|
| Back to top |
|
 |
Craig Stuntz [TeamB] Guest
|
Posted: Wed Apr 11, 2007 10:03 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
Martijn Tonies wrote:
| Quote: | ISQLDriver(Obj) := DriverInstance; // or only here?
This fails with the AV (read of address 00000001A).
|
Hmmm... I'd suggest rebuilding with debug DCUs and trace into the
assignment to see if you can get any closer to the error.
--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
Please read and follow Borland's rules for the user of their
server: http://support.borland.com/entry.jspa?externalID=293 |
|
| Back to top |
|
 |
Craig Stuntz [TeamB] Guest
|
Posted: Wed Apr 11, 2007 10:38 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
Martijn Tonies wrote:
| Quote: | Would this mean the "Out" parameter isn't NIL? Even if so, why should
it? Isn't it "Out" only?
|
Yes and no. "out" is the same as "var". "out" params *should* be used
as out only, but the compiler doesn't enforce it.
Yes, it means the out is non-nil. Calling _Release on a non-nil and
not-pointing-to-any-allocated-object-implementing-an-interface can
indeed raise an AV, since _Release is virtual. Your workaround seems
correct to me.
--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
IB 6 versions prior to 6.0.1.6 are pre-release and may corrupt
your DBs! Open Edition users, get 6.0.1.6 from http://mers.com |
|
| Back to top |
|
 |
Peter Sawatzki Guest
|
Posted: Fri Apr 13, 2007 11:50 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
Martijn,
this is a bug in dbxadapter30 because the C++ definitions of
ISQLCommand30.execute, ISQLCommand30.executeImmediate and
ISQLCommand30.getNextCursor define their parameters as OUT while the
Pascal definition is VAR. I filed a bug report on this earlier (QC
#41784) already and this should be fixed for the RTM release, it is
marked as fixed for build 2620 (RTM= 2627). I'm wondering why you are
still seeing this. In my own driver I circumvented the crash by
explicitly assigning nil to the variable casted to a pointer.
from the QC: "Original definition for ISQLCommand30.execute from
BDS2006 is:
function execute(var Cursor: ISQLCursor30): SQLResult; stdcall;
if an old style Pascal written dbx3 driver implements/derives from
ISQLCommand30, the first assignment to Cursor in the driver will crash,
as dbxadapter30.dll is passing a non-nil value for Cursor (and in a
sense dbxadapter is correctly doing so, it assumes Cursor is an out
parameter). Of course the driver could be modified by changing the
definition to "out Cursor: ISQLCursor30" or the driver writer could do
a "Pointer(Cursor):= nil" as the first thing in the implementing
method, but this is probably not the case for most drivers.
So I suggest to modify dbxadapter30.dll to initialize all (incorrectly
defined) parameters it expects to receive. I think the following calls
need to be modified:
before calling ISQLCommand30.execute, set Pointer(Cursor):= nil;
before calling ISQLCommand30.executeImmediate, set Pointer(Cursor):=
nil;
before calling ISQLCommand30.getNextCursor, set Pointer(Cursor):= nil;"
Peter
Martijn Tonies wrote:
| Quote: | Hi,
I'm working on making our driver DBX3 compatible. So far so good, I'd
say.
D2006 loads the driver without problems and displays data.
However, when trying to use the driver with D2007, the DBXDynalink
thingy tries to load it and the driver raises an error.
It happens here:
function TDBXDynalinkDriverCommonLoader.Load(DriverDef:
TDBXDriverDef): TDBXDriver;
...
ErrorResult := FMethodTable.FDBXLoader_GetDriver(Count, Names,
Values,
TDBXWideStringBuilder(ErrorMessageBuilder),
FDriverHandle); ...
I have no idea whatsoever what's going on. I cannot debug the driver
from the D2007 IDE, cause it cannot compile it (due to missing
dbExpress interfaces, as those are deprecated).
How are we supposed to compile DBX3 drivers with D2007??
Got any clue with regard to the driver?
|
-- |
|
| Back to top |
|
 |
Peter Sawatzki Guest
|
Posted: Fri Apr 13, 2007 11:55 pm Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
Craig,
the bug is in dbxadapter30 and the fact that the Pascal definions of
Cursor in ISQLCommand30.execute, ISQLCommand30.executeImmediate and
ISQLCommand30.getNextCursor are VAR and the C++ definions are OUT. As
soon as the Pascal code assigns something to Cursor the "Cursor" is
freed before the assignment. See my QC # 41784 which is marked as fixed
for build 2620.
Peter
Craig Stuntz [TeamB] wrote:
| Quote: | Martijn Tonies wrote:
function getSQLDriverFB(sVendorLib : PChar; sResourceFile : PChar;
out Obj): SQLResult; stdcall;
Is this CodeGear's code or yours? I don't know much about dbExpress
innards, but returning an interface as an untyped argument is odd to
say the least.
|
-- |
|
| Back to top |
|
 |
Martijn Tonies Guest
|
Posted: Sat Apr 14, 2007 12:24 am Post subject: Re: DBX3 driver raises AV when loaded by DynaLink DBX 4 |
|
|
Hello Peter,
In the end, I figured this out, or at least, for ISQLDriver.
I've got another problem with the adapter now, the
Dynalink.DerivedOpen fails, please see my other post
in the dbExpress newsgroup.
--
Martijn Tonies
Database Workbench - tool for InterBase, Firebird, MySQL, NexusDB, Oracle &
MS SQL Server
Upscene Productions
http://www.upscene.com
My thoughts:
http://blog.upscene.com/martijn/
Database development questions? Check the forum!
http://www.databasedevelopmentforum.com
If you can't dazzle em with brilliance, baffle em with bullshit
| Quote: | this is a bug in dbxadapter30 because the C++ definitions of
ISQLCommand30.execute, ISQLCommand30.executeImmediate and
ISQLCommand30.getNextCursor define their parameters as OUT while the
Pascal definition is VAR. I filed a bug report on this earlier (QC
#41784) already and this should be fixed for the RTM release, it is
marked as fixed for build 2620 (RTM= 2627). I'm wondering why you are
still seeing this. In my own driver I circumvented the crash by
explicitly assigning nil to the variable casted to a pointer.
from the QC: "Original definition for ISQLCommand30.execute from
BDS2006 is:
function execute(var Cursor: ISQLCursor30): SQLResult; stdcall;
if an old style Pascal written dbx3 driver implements/derives from
ISQLCommand30, the first assignment to Cursor in the driver will crash,
as dbxadapter30.dll is passing a non-nil value for Cursor (and in a
sense dbxadapter is correctly doing so, it assumes Cursor is an out
parameter). Of course the driver could be modified by changing the
definition to "out Cursor: ISQLCursor30" or the driver writer could do
a "Pointer(Cursor):= nil" as the first thing in the implementing
method, but this is probably not the case for most drivers.
So I suggest to modify dbxadapter30.dll to initialize all (incorrectly
defined) parameters it expects to receive. I think the following calls
need to be modified:
before calling ISQLCommand30.execute, set Pointer(Cursor):= nil;
before calling ISQLCommand30.executeImmediate, set Pointer(Cursor):=
nil;
before calling ISQLCommand30.getNextCursor, set Pointer(Cursor):= nil;"
Peter
Martijn Tonies wrote:
Hi,
I'm working on making our driver DBX3 compatible. So far so good, I'd
say.
D2006 loads the driver without problems and displays data.
However, when trying to use the driver with D2007, the DBXDynalink
thingy tries to load it and the driver raises an error.
It happens here:
function TDBXDynalinkDriverCommonLoader.Load(DriverDef:
TDBXDriverDef): TDBXDriver;
...
ErrorResult := FMethodTable.FDBXLoader_GetDriver(Count, Names,
Values,
TDBXWideStringBuilder(ErrorMessageBuilder),
FDriverHandle); ...
I have no idea whatsoever what's going on. I cannot debug the driver
from the D2007 IDE, cause it cannot compile it (due to missing
dbExpress interfaces, as those are deprecated).
How are we supposed to compile DBX3 drivers with D2007??
Got any clue with regard to the driver?
--
|
|
|
| Back to top |
|
 |
|
|
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
|
|