Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.


Btrieve BTRCALL is not returning the Record Key

Btrieve BTRCALL is not returning the Record Key

Hello all. I am consuming WBTRV32.dll in C# with only one external call. The call is defined like so:

CODE --> C#

[DllImport("WBTRV32.dll", CharSet = CharSet.Ansi)]
        internal static extern short BTRCALL(
            ushort operation,
            [MarshalAs(UnmanagedType.LPArray, SizeConst = 128)] byte[] posBlk,
            [MarshalAs(UnmanagedType.Struct, SizeConst = 255)] ref RecordBuffer databuffer,
            ref int dataLength,
            [MarshalAs(UnmanagedType.LPArray, SizeConst = 255)] char[] keyBffer,
            ushort keyLength,
            ushort keyNum); 

To collect a record, I am making the following two calls:

CODE --> C#

byte[] positionBlock = new byte[128];
var dataBuffer = new RecordBuffer();
int bufferLength = Marshal.SizeOf(dataBuffer);

var status = BTRCALL((ushort)BtrvOperation.Open, positionBlock, ref dataBuffer, ref bufferLength, _fileNameArray, 0, 0); // BtrvOperation.Open == 0
if (status == 0) {
    status = BTRCALL((ushort)BtrvOperation.GetFirst, positionBlock, ref dataBuffer, ref bufferLength, _fileNameArray, 0, 0); // BtrvOperation.GetFirst == 12

In the old C++ code, the struct for this record looks like this:

CODE --> C#

struct myRecord {
    int RecordNo;
    char UserName[21];
    char Address[51];
    . . . .

The Data Buffer for my calls, as I show above, is an object called RecordBuffer, which looks like this:

CODE --> C#

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
    public struct RecordBuffer
        public short DocType;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2500)] public char[] DocDescPlural;
        public short Sorting;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2500)] public char[] DocDescSingle;
        public short CopyOtherThanSrc;
        public double DefaultNotebookNo;

In a command line, when I call butil -recover users.btr userRecover.txt, I get the following:

265,[SOH][NUL]TEST1, USERNAME1 [NUL]1234 TEST AVE, CITY BLAH BLAH . . . . . . . . . . . . .
265,[STX][NUL]TEST2, USERNAME2 [NUL]1234 TEST AVE, CITY BLAH BLAH . . . . . . . . . . . . .
265,[ETX][NUL]TEST3, USERNAME3 [NUL]1234 TEST AVE, CITY BLAH BLAH . . . . . . . . . . . . .

And if I call this in the command line: butil -stat users.btr, I am told:

CODE --> C#

File Version = 9.50
Page Size = 2048
Page Preallocation = No
Key Only = No
Extended = No

Total Number of Records = 1190
Record Length = 265
Record Compression = No
Page Compression = No
Variable Records = No

Available Linked Duplicate Keys = 0
Balanced Key = No
Log Key = 0
System Data = No
Total Number of Keys = 7
Total Number of Segments = 8

Key         Position        Type            Null Values*               ACS
    Segment          Length           Flags              Unique Values
  0    1         1       2  AutoInc      M      --              1190    --
  1    1         3      20  String       MD     --              1139    --
  2    1   . . . . . etc etc 

I am near certain that the first two bytes (e.g.: [ETX][NUL]) is the RecordNo, while the next 21 (null-terminated) is the UserName, etc. It aligns with my struct perfectly.

But when I run my application, my dataBuffer comes back with a "RecordBuffer" which has a DocDescPlural value like so:

CODE --> C#

[0]: 84 'T'
[1]: 69 'E'
[2]: 83 'S'
[3]: 84 'T'
 . . . . . . 

The entire record for the GetFirst, and subsequent GetNext calls comes back, EXCEPT For the RecordNo. The first two bytes are skipped for some reason. I've tried this with multiple tables and all of the tables return the records exactly as expected, Sans the AutoInc Key.

RE: Btrieve BTRCALL is not returning the Record Key

Due to a complete lack of understanding of Btrieve, I thought that the RecordBuffer I was using was a structure that was expected for Btrieve to fill in, and DocDescPlural was the portion of the returned data type which represented the record.

But it turns out the dataBuffer is just a dataBuffer, so I just ended up expecting back a char array, and all of my data came back as expected.

Weird that the "DocType" didn't end up having the record number in it, which I would totally expect. That would have given me a clue at least as to what was going on. But at least I figured it out.

Thanks for the possible future help, but I figured it out just after posting. WHEEEEEE

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!


Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close