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

Strange FieldPut() error

13 views
Skip to first unread message

Olli Kekäläinen

unread,
Oct 30, 2006, 10:03:33 AM10/30/06
to
Hi all!

Does anybody have a clue why the call of fieldput() - or vodbfieldput() -
causes Data type error with an Arg {(0x0000)0x0DCB0464} CLASS
InValidVoObject? What does it mean?

The data type of the field which I tried to put a value to is "C" and the
second parameter for fieldput() is a string as it should be.

Any clues?

Olli


Jamal

unread,
Oct 30, 2006, 10:42:07 AM10/30/06
to
Olli,

Could you make a sample that shows the error?
Have you checked the data for corruption?
What RDD are using?
What version of VO are you using?

Jamal

"Olli Kekäläinen" <olli.kekalainen_x_x_@_x_x_pp.inet.fi> wrote in message
news:9vo1h.179$_p2...@read3.inet.fi...

Geoff

unread,
Oct 30, 2006, 3:34:42 PM10/30/06
to
Olli.

You need to show us some code. Otherwise we are just guessing. It could
be a whole lot of things.

Geoff


"Olli Kekäläinen" <olli.kekalainen_x_x_@_x_x_pp.inet.fi> wrote in

message news:9vo1h.179$_p2...@read3.inet.fi:

Olli Kekäläinen

unread,
Oct 31, 2006, 3:33:05 AM10/31/06
to
Hi,

Ok, I try to be more specific.

First, I use VO 2.7b and the RDD is DBFCDX.

I didn't offer any code because it's so complicated.
Here is a highly simplified example of the code which causes the error.
Error occurs only when I executed the code in a sub-thread.
In main thread it works just fine.

LOCAL dwSelect AS DWORD
LOCAL dwRecno AS DWORD
LOCAL dwField AS DWORD
LOCLA uValue AS USUAL

dwSelect := 1
dwRecord := 1
dwField := 1

IF (vodbSetSelect( longint( _CAST, dwSelect )) = dwSelect)
vodbRLock( dwRecno )
IF vodbGoTo( dwRecno )
uValue := "0000000000000001"

// next line raises Data type error
// with an Arg
// {(0x0000)0x0DCB0464} CLASS InValidVoObject

vodbFieldPut( dwField, uValue )
ENDIF
ENDIF


Olli


Olli Kekäläinen

unread,
Oct 31, 2006, 3:50:50 AM10/31/06
to
I forget to mention that the table is opened as shared...

Olli


Sherlock

unread,
Oct 31, 2006, 3:59:47 AM10/31/06
to
Olli

snip[ vodbFieldPut( dwField, uValue ) ]

What is fieldtype fieldpos(1).... which dwField ?

Is it Character or Memo ?

snip[ uValue := "0000000000000001" ]

You are trying to put a 16 character string in this field

Phil McGuinness
-------

Olli Kekäläinen

unread,
Oct 31, 2006, 4:12:55 AM10/31/06
to
Hi Phil,

The fieldtype is Character.

Olli

"Sherlock" <sher...@sherlock.com.au> wrote in message
news:1162285187....@i42g2000cwa.googlegroups.com...

Geoff

unread,
Oct 31, 2006, 4:28:28 AM10/31/06
to
Olli.

What do yo mean by a "sub thread" ?

Geoff


"Olli Kekäläinen" <olli.kekalainen_x_x_@_x_x_pp.inet.fi> wrote in

message news:5TD1h.63$YX2...@read3.inet.fi:

Olli Kekäläinen

unread,
Oct 31, 2006, 4:34:26 AM10/31/06
to
Hi Geoff,

>
> What do yo mean by a "sub thread" ?
>

A thread created with CreateVoThread() function.

Olli


Sherlock

unread,
Oct 31, 2006, 7:07:52 AM10/31/06
to

Olli

snip[ > The fieldtype is Character. ]

OK..

What happens when you use this syntax

local oDB as DBSERVER
local uValue := "0000000000000001" as string

SetDefault("c:\yourdirectory\")
SetInternational(#CLIPPER)
SetAnsi(FALSE) // CDX Compatibility
SetExclusive( FALSE ) // Need MULTI USER ACCESS - for sure...
RDDSETDEFAULT("DBFCDX")

oDB := DBSERVER{ "yourdatabase", DBSHARED }
if oDB:Used
if oDB:RLock()
oDB:FIELDPUT( 1, uValue )
oDB:Unlock()
endif
oDB:Close()
oDB := NULL_OBJECT
endif

Does this code work for you on your database ?

Phil McGuinness

Ginny Caughey

unread,
Oct 31, 2006, 7:26:54 AM10/31/06
to
Olli,

If you want to access DBF files using multithreading, you must keep separate
workareas for each thread using record locking like you would for separate
apps. The RDDs are not thread safe.

--
Ginny


"Olli Kekäläinen" <olli.kekalainen_x_x_@_x_x_pp.inet.fi> wrote in message

news:CME1h.82$YX2...@read3.inet.fi...

Olli Kekäläinen

unread,
Oct 31, 2006, 7:49:19 AM10/31/06
to
Hi Ginny,

> If you want to access DBF files using multithreading, you must keep
> separate workareas for each thread using record locking like you would for
> separate apps. The RDDs are not thread safe.
>

So I already figured out.
After several tests today I noticed that the DBFCDX driver for some
reason closes the workarea tables (although opened in main thread)
in the end of the sub thread. The error message I got in first
place (when calling fieldput() during next sub thread execution)
was quite misleading.

Thank you, Ginny, for confirming my assumptions.

Olli

PS. I would be happy if DBFCDX driver were thread safe in VO 2.8


Olli Kekäläinen

unread,
Oct 31, 2006, 7:50:11 AM10/31/06
to
Hi Phil,

See my answer to Ginny below....

Thanks anyway!

Olli


"Sherlock" <sher...@sherlock.com.au> wrote in message

news:1162296472....@i42g2000cwa.googlegroups.com...

Ginny Caughey

unread,
Oct 31, 2006, 8:10:58 AM10/31/06
to
Olli,

I don't think it's likely that the RDDs will ever become thread safe. More
and more apps that might have been written to use DBF files are using SQL
databases, but even there I think it's prudent to use separate connections
for each thread.

It's not that hard to construct apps in such a way that you open, close,
read and write to DBF files all within the context of each thread and just
treat each thread as you would separate apps. I have such an app in
production for many years now with no problems. Here's what the code looks
like that launches the threads. Note that I'm using a structure to pass
parameters to each thread. The Output function just uses a critical section
to write to a log file in a thread safe manner for testing purposes. Each
thread's polling loop checks the value of CancelRequested to know when it
must shut down, and the app doesn't exit until all threads have done so to
prevent data loss.

FOR i := 1 TO nThreads
// allocate memory for structure and fill with data to pass to threaded
function RunPollingLoop
pInfo[i] := MemAlloc(_sizeof(WatchInfo))
pInfo[i].ScaleNumber := aPorts[i, 1]
pInfo[i].PortNumber := aPorts[i, 2]
pInfo[i].hWnd := SELF:Handle(0)
Output("GUI thread - Starting scale "+AsString(pInfo[i].ScaleNumber))
// launch worker thread
hThreads[i] := CreateVOThread(null, 0, @RunPollingLoop(), pInfo[i], 0,
@dwIDs[i])
// reduce priority of worker thread so GUI thread will repaint normally
//SetThreadPriority(hThreads[i], THREAD_PRIORITY_BELOW_NORMAL)
SetThreadPriority(hThreads[i], THREAD_PRIORITY_LOWEST)
NEXT
// just sit there until Cancel button pressed while the threads do all the
work
WHILE !CancelRequested
Sleep(100) // needed to give the GUI thread a chance to process messages
oApp:ExecWhileEvents()
END

--
Ginny


"Olli Kekäläinen" <olli.kekalainen_x_x_@_x_x_pp.inet.fi> wrote in message

news:jDH1h.148$YX2...@read3.inet.fi...

Olli Kekäläinen

unread,
Oct 31, 2006, 8:39:07 AM10/31/06
to
Ginny,


> I don't think it's likely that the RDDs will ever become thread safe. More
> and more apps that might have been written to use DBF files are using SQL
> databases, but even there I think it's prudent to use separate connections
> for each thread.

Yes, you are right.


> It's not that hard to construct apps in such a way that you open, close,
> read and write to DBF files all within the context of each thread and just
> treat each thread as you would separate apps.

I know. I just tried to keep my (data)server application
(it provides data services over the tcp/ip) as quick as possible and
tried first to implement it without opening and closing tables for every
request.
Now, I'm wiser :)

And thanks for your code snippet.


Olli


0 new messages