PDA

View Full Version : VBA string data type in cobol



Ronald_yoh
11-30-2008, 06:20 PM
Hi there,

I have a dll cobol and trying to call this dll from VBA. now the problem is every time the VBA passing a string value byRef to cobol dll, the application will be terminated with error message: "114 ATTEMPT TO ACCESS ITEM BEYOND BOUNDS"

I've tested with integer data type and it works perfectly.

any ideas?

Cheers
Ron

Oorang
12-01-2008, 11:22 AM
Hi Ronald,
I can't give you a specific answer as I don't have the dll in question. But I am going to give you a couple things to try and see what sticks.
First of lets talk about datatypes between languages. A datatype just specifies an amount of memory to reserve and a scheme for reading, editing, and expanding/shrinking the spot in memory. A Cobol String is not stored in memory the same way a vb string is. In VB strings are variable length by default and unicode. That is to say the amount of memory reserved can grow or shrink depending on the amount of data you store in the string. And each character is stored as two bytes (unicode). So if you look at a vb string in memory you have 4 bytes (the string header) that say how long the string is, then a series of bytes that contains the actual character data (2 bytes for each character) and finally 2 more bytes that are empty (null) that terminates the string.
Now how to pass to variable? Well it depends on what the dll was expecting. It could be expecting a pointer or a variable etc.

So what you need to find out about your dll string is the following:
-Is it ascii or unicode (I suspect it will be unicode)?
-Is it variable or fixed length (I suspect it will be fixed)?
-Is it null terminated?
-Is it expecting a pointer?

Some, none, or all of those things may true of your specific dll depending on how it was written. I have included example code of the techniques I discussed. I hope it at least gets you started.

Option Explicit
Private Declare Sub MyDLLSub Lib "Cobol.dll" (ByRef myCobolString As Any)
Public Sub Example()
Dim strValue As String
Dim bytCobolString() As Byte
strValue = "ABCDEFGHIJ"
'Add null to string so converted value ends with a null:
strValue = strValue & vbNullChar
'Convert to byte array of ascii values:
bytCobolString = StrConv(strValue, vbFromUnicode)
'Call dll with a pointer to the the strings location in memory:
MyDLLSub StrPtr(bytCobolString())
End Sub

Ronald_yoh
12-01-2008, 02:53 PM
Hi,

Thanks for your reply.

However I'm still struggling to get this working

-Is it ascii or unicode (I suspect it will be unicode)?the cobol PIC X is ASCII (I guess) and VB string is unicode. I'm trying to pass just a simple text (e.g. hello)
-Is it variable or fixed length (I suspect it will be fixed)? - COBOL PIC X is fixed length and VB string is variable
-Is it null terminated? - no need NULL termination in Cobol
-Is it expecting a pointer? - not sure about this pointer. If I'm passing the pointer how do I get convert it back to string once passed back from the dll?

P.S. I've tried all your suggestions and still getting the same error...

please help

Oorang
12-01-2008, 03:30 PM
Hmmm, based on the error I don't think it's looking for pointer, I just threw that in there for throughness. I am just guessing at a few things. I would try this then (might not work):

Public Sub Example()
Dim strValue As String
Dim bytCobolString() As Byte
strValue = "ABCDEFGHIJ"
bytCobolString = StrConv(strValue, vbFromUnicode) 'Convert to byte array of ascii values:
MyDLLSub bytCobolString()'Pass as is:
End Sub

As far as passing it a pointer, if the dll is expecting a pointer there is a good chance that it will alter the string directly (not always).
A few more questions, could you post the declaration you are using?
Could you also post a summary of what the procedure is supposed to be doing?

Ronald_yoh
12-01-2008, 04:33 PM
Hi,

thanks for your reply.. i got this working.. (finally after 3 months struggling)..

for your reference in case someone's asking you the same questions in future.. steps to fix:

1) Need to specify the calling convention in cobol program (calling-convention 3 as winapi)

2) Passing paramater from the end. so if you have PARAM1 and PARAM2 in cobol program, when you call from VBA you need pass from PARAM2 and then PARAM1

3) you need to specify a length of string in VBA (e.g. dim sString as string * 100)

mate... thanks again for your help.. very appreciated...

Cheers
R

Oorang
12-02-2008, 07:32 AM
Sweet, I'm glad you got it:)