Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Btrieve BTRCALL is not returning the Record Key

Status
Not open for further replies.

Suamere

Programmer
Oct 2, 2017
2
0
0
US
Hello all. I am consuming WBTRV32.dll in C# with only one external call. The call is defined like so:

Code:
        [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:
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:
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:
    [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:
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:
[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.

 
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
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top