如何将数组从 Cobol 传递到 C# COM 对象
How to pass array from Cobol to C# COM object
我需要将数组从 MicroFocus Cobol 传递到 C# COM 对象。当我只传递字符串或数字时,它正在工作。但是使用数组我收到错误消息:
**异常 65537 未被 class oleexceptionmanager 捕获。
说明:"Server defined OLE exception"
(80070057): 参数不正确。
**
Cobol代码:
C $SET DIRECTIVES (SBODBC.DIR) NSYMBOL"NATIONAL"
$set ooctrl(+p)
identification division.
program-id. pokus444.
special-names.
environment-name is environment-name
environment-value is environment-value
decimal-point is comma.
class-control.
ChkAccNum is class "$OLE$CheckAccountNumber.AccountNumbers".
working-storage section.
01 ChkAccNumObj object reference.
01 accA.
05 acc pic x(34) occurs 100.
01 accR pic x(34).
procedure division.
main section.
display "Zacatek programu"
initialize accA accR
move '1234567890' to acc(1)
move '0987654321' to acc(2)
invoke ChkAccNum "new" returning ChkAccNumObj
invoke ChkAccNumObj "CheckAccount" using accA returning accR
display accR
exit
.
C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace CheckAccountNumber
{
[Guid("A80930D1-080F-4B04-A2C3-B637428556D6")]
public interface IAccountNumbers
{
[DispId(1)]
string CheckAccount(string[] accounts);
}
[Guid("65A771A0-0DDE-440D-9A4F-C71CEAEE3DF6"),
ClassInterface(ClassInterfaceType.None)]
public class AccountNumbers : IAccountNumbers
{
public AccountNumbers()
{
}
public string CheckAccount(string[] accounts)
{
return accounts[1];
}
}
}
如果您查看已注册 C# 的类型库 class,您会发现它需要一个 BSTR(string) 类型的 SafeArray:
]
interface IAccountNumbers : IDispatch {
[id(0x00000001)]
HRESULT CheckAccount(
[in] SAFEARRAY(BSTR) accounts,
[out, retval] BSTR* pRetVal);
};
Micro Focus COBOL(Net Express 和 Visual COBOL)支持安全数组,因此您可以使用如下代码:
$set ooctrl(+p)
identification division.
program-id. pokus444.
special-names.
environment-name is environment-name
environment-value is environment-value
decimal-point is comma.
class-control.
mftech CharacterArray is class "chararry"
mftech OLESafeArray is class "olesafea"
ChkAccNum is class "$OLE$CheckAccountNumber.AccountNumbers".
working-storage section.
mftech copy mfole.
mftech copy olesafea.
01 ChkAccNumObj object reference.
01 accA.
05 acc pic x(34) occurs 100.
01 accR pic x(34).
mftech 01 ws-stringArray object reference.
mftech 01 ws-vartype pic 9(4) comp-5.
mftech 01 ws-dimension pic 9(4) comp-5.
mftech 01 ws-saBound SAFEARRAYBOUND occurs 1.
mftech 01 ws-iIndex pic 9(9) comp-5.
mftech 01 ws-len pic 9(9) comp-5.
mftech 01 ws-hresult pic 9(9) comp-5.
procedure division.
main section.
display "Zacatek programu"
initialize accA accR
move '1234567890' to acc(1)
move '0987654321' to acc(2)
***** Create a 1 Dimension OLESAFEARRAY to pass string array
move VT-BSTR to ws-vartype
move 1 to ws-dimension
move 2 to cElements of ws-saBound(1)
move 0 to llBound of ws-saBound(1)
invoke OLESafeArray "new" using by value ws-vartype
ws-dimension
by reference ws-saBound(1)
returning ws-stringArray
end-invoke
***** Populate 2 Elements in OLESAFEARRAY
move 0 to ws-iIndex
move 10 to ws-len
invoke ws-stringArray "putString"
using by reference ws-iIndex
by value ws-len
by reference acc(1)
returning ws-hresult
end-invoke
if ws-hresult not = 0
display "Die Gracefully"
stop run
end-if
move 1 to ws-iIndex
move 10 to ws-len
invoke ws-stringArray "putString"
using by reference ws-iIndex
by value ws-len
by reference acc(1)
returning ws-hresult
end-invoke
if ws-hresult not = 0
display "Die Gracefully"
stop run
end-if
invoke ChkAccNum "new" returning ChkAccNumObj
***** Pass across the OLESAFEARRAY
invoke ChkAccNumObj "CheckAccount" using ws-stringArray
returning accR
display accR
stop run.
我需要将数组从 MicroFocus Cobol 传递到 C# COM 对象。当我只传递字符串或数字时,它正在工作。但是使用数组我收到错误消息:
**异常 65537 未被 class oleexceptionmanager 捕获。
说明:"Server defined OLE exception"
(80070057): 参数不正确。
**
Cobol代码:
C $SET DIRECTIVES (SBODBC.DIR) NSYMBOL"NATIONAL"
$set ooctrl(+p)
identification division.
program-id. pokus444.
special-names.
environment-name is environment-name
environment-value is environment-value
decimal-point is comma.
class-control.
ChkAccNum is class "$OLE$CheckAccountNumber.AccountNumbers".
working-storage section.
01 ChkAccNumObj object reference.
01 accA.
05 acc pic x(34) occurs 100.
01 accR pic x(34).
procedure division.
main section.
display "Zacatek programu"
initialize accA accR
move '1234567890' to acc(1)
move '0987654321' to acc(2)
invoke ChkAccNum "new" returning ChkAccNumObj
invoke ChkAccNumObj "CheckAccount" using accA returning accR
display accR
exit
.
C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace CheckAccountNumber
{
[Guid("A80930D1-080F-4B04-A2C3-B637428556D6")]
public interface IAccountNumbers
{
[DispId(1)]
string CheckAccount(string[] accounts);
}
[Guid("65A771A0-0DDE-440D-9A4F-C71CEAEE3DF6"),
ClassInterface(ClassInterfaceType.None)]
public class AccountNumbers : IAccountNumbers
{
public AccountNumbers()
{
}
public string CheckAccount(string[] accounts)
{
return accounts[1];
}
}
}
如果您查看已注册 C# 的类型库 class,您会发现它需要一个 BSTR(string) 类型的 SafeArray:
]
interface IAccountNumbers : IDispatch {
[id(0x00000001)]
HRESULT CheckAccount(
[in] SAFEARRAY(BSTR) accounts,
[out, retval] BSTR* pRetVal);
};
Micro Focus COBOL(Net Express 和 Visual COBOL)支持安全数组,因此您可以使用如下代码:
$set ooctrl(+p)
identification division.
program-id. pokus444.
special-names.
environment-name is environment-name
environment-value is environment-value
decimal-point is comma.
class-control.
mftech CharacterArray is class "chararry"
mftech OLESafeArray is class "olesafea"
ChkAccNum is class "$OLE$CheckAccountNumber.AccountNumbers".
working-storage section.
mftech copy mfole.
mftech copy olesafea.
01 ChkAccNumObj object reference.
01 accA.
05 acc pic x(34) occurs 100.
01 accR pic x(34).
mftech 01 ws-stringArray object reference.
mftech 01 ws-vartype pic 9(4) comp-5.
mftech 01 ws-dimension pic 9(4) comp-5.
mftech 01 ws-saBound SAFEARRAYBOUND occurs 1.
mftech 01 ws-iIndex pic 9(9) comp-5.
mftech 01 ws-len pic 9(9) comp-5.
mftech 01 ws-hresult pic 9(9) comp-5.
procedure division.
main section.
display "Zacatek programu"
initialize accA accR
move '1234567890' to acc(1)
move '0987654321' to acc(2)
***** Create a 1 Dimension OLESAFEARRAY to pass string array
move VT-BSTR to ws-vartype
move 1 to ws-dimension
move 2 to cElements of ws-saBound(1)
move 0 to llBound of ws-saBound(1)
invoke OLESafeArray "new" using by value ws-vartype
ws-dimension
by reference ws-saBound(1)
returning ws-stringArray
end-invoke
***** Populate 2 Elements in OLESAFEARRAY
move 0 to ws-iIndex
move 10 to ws-len
invoke ws-stringArray "putString"
using by reference ws-iIndex
by value ws-len
by reference acc(1)
returning ws-hresult
end-invoke
if ws-hresult not = 0
display "Die Gracefully"
stop run
end-if
move 1 to ws-iIndex
move 10 to ws-len
invoke ws-stringArray "putString"
using by reference ws-iIndex
by value ws-len
by reference acc(1)
returning ws-hresult
end-invoke
if ws-hresult not = 0
display "Die Gracefully"
stop run
end-if
invoke ChkAccNum "new" returning ChkAccNumObj
***** Pass across the OLESAFEARRAY
invoke ChkAccNumObj "CheckAccount" using ws-stringArray
returning accR
display accR
stop run.