LS C API problem

I’m sort of at my wit’s end here. I’ve had a fair amount of success writing programs using the the LS2C API, but this little snippet keeps crashing my Notes client. In short, I’m cycling through all selected Bookmark documents in the Bookmarks database and I’m crashing right at the call to ConvertItemToText.

Any idea what I’m missing? For now, I just want to print out the contents of the URL field. If I get more adventurous, I’d like to write back to it.

I’ve included my function declaration too.

Thanks

==================

Declare Function W32_ConvertItemToText Lib "nnotes" Alias "ConvertItemToText" (Byval item_value As Any, Byval item_length As Long, Byval delim As String, Byval charsPerLine As Integer, buffer_handle As Long, buffer_length As Long, Byval stripTabs As Long) As Integer

Sub Initialize

Dim s As New NotesSession

Dim dc As notesdocumentcollection

Dim doc As NotesDocument

Dim iBlock As Blockid, iType As Integer, vBlock As Blockid, vLen As Long

Dim buffLen As Long

Dim hBuf As Long

Dim irc As Integer, lineLen As Integer

Dim itemName As String



buffLen = 256



itemName = "URL"



Set dc = s.CurrentDatabase.UnprocessedDocuments



Set doc = dc.GetFirstDocument	

While Not doc Is Nothing

	irc = W32_NSFItemInfo(doc.handle, itemName, Len(itemName), iBlock, iType, vBlock, vLen)

	If irc = 0 Then

		

		irc = W32_ConvertItemToText(vBlock.pool, vLen, "\n", 80, hBuf, buffLen, 1)

		If irc = 0 Then

			pBuffer = W32_OSLockObject(vBlock.pool) + vBlock.block

			If pBuffer <> 0 Then

				Print "memory:", pBuffer

				

				W32_OSUnlockObject (vBlock.pool)

			End If

		Else

			Print getError(irc)

		End If

		

	Else

		Print getError(irc)

	End If

	

	Set doc = dc.GetNextDocument(doc)

Wend

End Sub

Subject: LS C API problem

for starters you need to pass BLOCKID (not “pool”) by value as the first parmater.

The declaration will not work like this (unless you store BLOCKID in Double variable as described in my 2nd suggestion below):

…Alias “ConvertItemToText” (Byval item_value As Any,

As discussed a number of times, you cannot pass structure directly by value no matter what you tell in declaration. Still in this case you can declare for example:

Byval item_value_pool As Long, ByVal item_value_block as Integer, …

and call it:

…(vblock.pool, vblock.block,…

or

  1. you can store BLOCKID in Double variable and declare:

Byval item_value As Double – some people in this forum prefer doing it this way, I usually do it as in my first suggestion.

The second place you could eventually expect problems is the line

pBuffer = W32_OSLockObject(vBlock.pool) + vBlock.block

assuming you have declared blockid as:

Type BLOCKID

pool as Long

block as Integer

End Type

Once the value of block is larger than largest signed Integer, this line will work incorrectly. You need, before adding, convert Block to Long taking into account that “block” is really unsigned.

Subject: RE: LS C API problem

Normunds,I was hoping you’d respond. I’ve been trying to piece this together from examples in your book and some off the API docs.

First off, I did not have blockID declared correctly, but even changing that, it’s still crashing at the same line, which now reads:

		irc = W32_ConvertItemToText(vBlock.pool, vBlock.block, "\n", 80, hBuf, buffLen, 1)

I understand a lot of this, but not all. hBuf is an unititialized Long (so value of zero) passed by ref, is this okay or do I need to allocate a buffer for it or some such thing like that?

Subject: RE: LS C API problem

oh and yes I changed the declaration so that it now reads:

Declare Function W32_ConvertItemToText Lib “nnotes” Alias “ConvertItemToText” (Byval item_value As Long, Byval item_length As Integer, Byval delim As String, Byval charsPerLine As Integer, buffer_handle As Long, buffer_length As Long, Byval stripTabs As Long) As Integer

Subject: RE: LS C API problem

About buffer – C API reference says:Note: the returned buffer must be deallocated by the caller via OSMemFree().

So you just provide a place to return the handle (no need to initialize anything), then lock the returned handle, etc.

About declaration, you got me absolutely wrong. Here is what I meant:

Declare Function W32_ConvertItemToText Lib LIB_W32 Alias {ConvertItemToText} (_

ByVal ItemValue_pool As Long, _

ByVal ItemValue_block As Integer, _

ByVal ItemValueLength As Long, _

ByVal LineDelimiter As LMBCS String, _

ByVal CharsPerLine As Integer, _

rethBuffer As Long, _

retBufferLength As Long, _

ByVal fStripTabs As Long) As Integer

So you pass BLOCKID as 2 variables instead of one.

Well you could also go to http://www.ls2capi.com site and check out the reference section. (I just put there a correct version of this declaration;-)

Subject: RE: LS C API problem

I saw the corrected version of the declaration on your site and now I understand what you mean.

Well, I’ll try to toy with this more this weekend.

Thanks for your help.

Subject: RE: LS C API problem

the only problem is that your code does not accomplish anything you could not get from LS using getFormattedText() for rich text. Or some other native LS method if the item happens to be of different type.