Having trouble calling PXCp_StringGetB from VB6. Any Help?

This Forum is for the use of Software Developers requiring help and assistance for Tracker Software's PDF-Tools SDK of Library DLL functions(only) - Please use the PDF-XChange Drivers API SDK Forum for assistance with all PDF Print Driver related topics or PDF-XChange Viewer SDK if appropriate.

Moderators: Tracker Support, TrackerSupp-Daniel, Chris - Tracker Supp, Vasyl-Tracker Dev Team, Sean - Tracker, Tracker Supp-Stefan

Post Reply
afalsow
User
Posts: 17
Joined: Thu Jun 14, 2012 1:28 pm

Having trouble calling PXCp_StringGetB from VB6. Any Help?

Post by afalsow » Fri Nov 02, 2012 8:22 pm

I am having trouble figuring out the proper calling convention to call PXCp_StringGetB from VB6.

I'm familiarizing myself with lower level functions (and am aware of Tracker's non-support policy re: same).

I have successfully executed the following functions in order:
  • PXCp_Init
    PXCpVB_ReadDocumentW
    PXCp_ET_AnalyzePageContent
    PXCp_GetPagesCount
    PXCp_llGetObjectsCount
    PXCp_llGetObjectByIndex
    PXCp_ObjectGetDictionary
    PXCp_DictionaryGetCount
    PXCp_StringCreate
    PXCp_DictionaryGetPair
    PXCp_StringGetB(hString, , BufLen) ... the first call with buf arg NULL to obtain buffer length
Why do I say they execute successfully? Because the result comes back non-negative and, where appropriate, contains what seems to be a reasonable value.

IN that code segment, BufLen is returned = 4
Then I want to actually get the string....

So I:
redim buf(BufLen) ... where buf was initially declared dim buf as Byte(), as it appears to me from docs that this is a ByteArray we're working with.

But no matter how I pass it to PXCp_StringGetB(hString, xxx, BufLen) (where 'xxx' is any number of attempts to properly pass the buffer... including "buf(0", "buf(1)", "byval buf", etc),

I get either an error or the value 0 (zero) returned in each of the 4 elements of the buf array.

For Example:
res = PXCp_StringGetB(lKeyName, ByVal buf(0), BufLen) returns res = 0 (which apparently means success), but buf() contains only zeroes in each element. lKeyName was a large (long) value at time of call.

How do I make that call to get good data back? I presume a proper result is that each element of the byte array will contain an ascii value? Do I need to use a Windows API such as CopyMemory or something? I will research that next.

I tried to experiment with this with the C# and VB.net examples (since I think those languages are bit more capable in such areas), but found that even the declares had not been provided for many of those functions.

Ivan - Tracker Software
Site Admin
Posts: 3587
Joined: Thu Jul 08, 2004 10:36 pm
Location: Vancouver Island - Canada
Contact:

Re: Having trouble calling PXCp_StringGetB from VB6. Any Hel

Post by Ivan - Tracker Software » Fri Nov 02, 2012 10:41 pm

I guess you have to declare this function as:

Code: Select all

Public Declare Function PXCp_StringGetB Lib "xcpro40" (ByVal hStrinng As Long, ByRef Buffer As Byte, ByRef BufLen As Long) As Long
this function will fill the memory pointed by Buffer with BufLen bytes. I'm not experienced with VB, and cannot say if VB's array is ok to use here.
Tracker Software (Project Director)

When attaching files to any message - please ensure they are archived and posted as a .ZIP, .RAR or .7z format - or they will not be posted - thanks.

afalsow
User
Posts: 17
Joined: Thu Jun 14, 2012 1:28 pm

Re: Having trouble calling PXCp_StringGetB from VB6. Any Hel

Post by afalsow » Fri Nov 02, 2012 11:11 pm

Thanks for the response.

I note that the declaration you have provided here appears to differ from that provided by Tracker Software in the sample code provided, specifically the XCPro40_Declares.bas which is installed by the Tracker installation process. In the Sample code, Tracker declares the PXCp_StringGetB as follows:

Public Declare Function PXCp_StringGetB Lib "xcpro40" (ByVal hString As Long, Optional ByRef buf As Long, Optional ByRef pBufLen As Long) As Long

Could I ask someone at Tracker Software to confirm which version is correct? Is the buffer to be declared long (as in the Tracker-installed sample code) or byte as in your post here?

afalsow
User
Posts: 17
Joined: Thu Jun 14, 2012 1:28 pm

Re: Having trouble calling PXCp_StringGetB from VB6. Any Hel

Post by afalsow » Sun Nov 04, 2012 2:19 pm

I have spent much of the past couple of days experimenting in VB.NET in an attempt to identify the proper declaration for PXCp_StringGetB (in XCPR4_Declares.vb) and the proper way to pass the buffer to the SDK. I had also initially attempted to get this function working in the VB6 version, but also failed to determine proper way to pass the buffer.

In relying upon documentation which defines PXCp_StringGetB as follows:

PXCp_StringGetB retrieves a specified PDF string in binary data format.

HRESULT PXCp_StringGetB(
HPDFSTRING hString,
BYTE* buf,
DWORD* pbufLen
);

hString: [in] hString specifies the PDF string handle.

buf: [in] buf is a pointer to a buffer that receives string content presented as binary data. This parameter may be NULL.

pbufLen: [in/out] pbufLen is a pointer to variable that specifies the size of the buffer in bytes. If buf is NULL then pbufLen creates a buffer sufficient to receive the binary data.



I have tried declaring the function (ie: in XCPro40_Declares.vb) as either a byte array (which is what I gather it should be.... based on the documented definition), and also as a long.

So I have tried a variety of:

<DllImport("xcpro40.dll")> Public Shared Function PXCp_StringGetB(ByVal hString As Integer, ByVal buf As Long, ByVal BufLen As Integer) As Integer
End Function

<DllImport("xcpro40.dll")> Public Shared Function PXCp_StringGetB(ByVal hString As Integer, ByVal buf As Byte, ByVal BufLen As Integer) As Integer
End Function

<DllImport("xcpro40.dll")> Public Shared Function PXCp_StringGetB(ByVal hString As Integer, ByVal buf As Byte(), ByVal BufLen As Integer) As Integer
End Function

<DllImport("xcpro40.dll")> Public Shared Function PXCp_StringGetB(ByVal hString As Integer, ByVal buf As IntPtr, ByVal BufLen As Integer) As Integer
End Function


I have experimented with Marshaling, IntPtr, passing the array "naked", ie: (buf, or buf(0), or buf(1) - in case 1-based).

Every approach attempted results in either res < 0 (error) or res = 0 AND the buffer contains only zeroes.

The Delphi version does work, and does show that valid data should be returned in the buffer. But I cannot find an approach that works. I have utilized other analysis tools, also, to confirm proper data should be coming back for the designated dictionary and key.

Unfortunately, PXCp_StringGetB appears to be the only function passing a BYTE* buf... so there is no other function to look at in an attempt to solve this puzzle.

Also puzzling me is how to accommodate the need to specify buffer as optional (in the case of first retrieving buflen). What is the proper default value... particularly if it must be declared as a byte array or some variant thereof? What is a proper default value for a byte array?

THOROUGHLY STUMPED on this SDK declaration/calling issue.

afalsow
User
Posts: 17
Joined: Thu Jun 14, 2012 1:28 pm

Re: Having trouble calling PXCp_StringGetB from VB6. Any Hel

Post by afalsow » Sun Nov 04, 2012 2:57 pm

Ok, so I just went back to try another go in VB6. And I got it!

The function should be properly declared as:

Public Declare Function PXCp_StringGetB Lib "xcpro40" (ByVal hString As Long, Optional ByVal buf As Long, Optional ByRef pBufLen As Long) As Long

Then the call, where buf is a Byte Array is:
res = PXCp_StringGetB(lKeyName, VarPtr(buf(0)), BufLen)

And I get back proper ascii values in each element of buf! YEAH!

Now I need to translate this to VB.net.

I'll assume that the declaration portion simply gets translated to Optional ByVal buf as Long = 0 (as the docs state this must be / should be optional... and if optional, VB.net requires a default value in declaration)
And we'll see how that works out.
And I suspect (VB6) VarPtr does not exist in VB.net, so that will require some research.
Last edited by afalsow on Mon Nov 05, 2012 1:15 pm, edited 1 time in total.

User avatar
Tracker Supp-Stefan
Site Admin
Posts: 13312
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Re: Having trouble calling PXCp_StringGetB from VB6. Any Hel

Post by Tracker Supp-Stefan » Mon Nov 05, 2012 12:11 pm

Hi afalsow,

Glad to hear you got it working in VB6!
Thanks for sharing your solution - hope it would be useful to others as well!

And fingers crossed translating to VB.net won't be too hard!

Cheers,
Stefan

afalsow
User
Posts: 17
Joined: Thu Jun 14, 2012 1:28 pm

Re: Having trouble calling PXCp_StringGetB from VB6. Any Hel

Post by afalsow » Mon Nov 05, 2012 1:14 pm

I've come up against a wall, again, on the absence of VarPtr function in VB.net

While I have researched and found a number of ways that are supposed to emulate this function in VB.net (primarily using GCHandle), these approaches all fail (most often with memory access violation errors). I've stumbled upon posts that suggest the memory segments must be offset, etc. But every variation attempted so far has failed with error.

As the PXCp_StringGetB appears to be the ONLY function in the entire SDK that passes a BYTE* buf, I am beginning to suspect it may not have been tested by Tracker Software for use in .net

While the function *does* work in older technologies (Delphi and VB6) I feel it may work *only* in those development environments.

User avatar
Tracker Supp-Stefan
Site Admin
Posts: 13312
Joined: Mon Jan 12, 2009 8:07 am
Location: London
Contact:

Re: Having trouble calling PXCp_StringGetB from VB6. Any Hel

Post by Tracker Supp-Stefan » Mon Nov 05, 2012 2:04 pm

Thanks for the update afalsow,

I will check this with our devs and we will post back here when we have some further news.

Best,
Stefan

Ivan - Tracker Software
Site Admin
Posts: 3587
Joined: Thu Jul 08, 2004 10:36 pm
Location: Vancouver Island - Canada
Contact:

Re: Having trouble calling PXCp_StringGetB from VB6. Any Hel

Post by Ivan - Tracker Software » Tue Nov 06, 2012 6:29 pm

Maybe this information would be helpful: http://msdn.microsoft.com/en-us/library ... S.80).aspx
Tracker Software (Project Director)

When attaching files to any message - please ensure they are archived and posted as a .ZIP, .RAR or .7z format - or they will not be posted - thanks.

Post Reply