我需要将数组从MicroFocus Cobol传递到C#COM对象。当我只传递字符串或数字时,它起作用了。但是用数组我得到了错误信息:
**异常65537未被类oleexceptionmanager捕获。
说明:“服务器定义的OLE异常”
(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];
}
}
}
答案 0 :(得分:3)
如果您为注册的C#类签出typelib,您将看到它期望的类型为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.