У меня были похожие проблемы при передаче разных видов массивов из C # в неуправляемый код Delphi / C / C ++ через COM / OLE интерфейс.
Вот что я нашелработает:
IDL file definitions:
[
uuid(270FB76B-8CA7-47CA-AAA-7C76F55F39A2),
version(1.0),
helpstring("Interface for Logic Object"),
oleautomation
]
interface ILogic: IUnknown
{
[
id(0x00000065)
]
HRESULT _stdcall Sample1([in] double value, [in, out] int * length, [in, out] VARIANT * bytes );
[
id(0x00000066)
]
HRESULT _stdcall Sample2([in, out] SAFEARRAY(double) array );
[
id(0x00000067)
]
HRESULT _stdcall Echo([in] LPWSTR input, [in, out] LPWSTR * ouput );
};
Самый простой способ, используя VARIANT :
, он работает с любыми типами, такими как int, double и т. д.
Код Delphi:
function TLogic.Sample1(value: Double; var length: SYSINT;
var bytes: OleVariant): HResult; stdcall;
var test: Byte;
begin
Result := 1;
test := 7;
for i := 0 to length do
bytes[i] := test;
end;
end;
После regsrv32.exe name-of-lib.dll и добавления библиотеки COM к ссылкам с использованием Visual Studio
C # код:
ILogic test = new IClassLogic(); //COM inctance of interface (counter-intuitive for C#)
byte[] bytes = new byte[100000];
object obj = (object)bytes;
test.Sample1(2.0, ref length, ref obj);
Более сложный способ с использованием SAFEARRAY (кажется, не работает с байтом, но хорошо работает с другими типами данных):
SAFEARRAY (байт) => C # Массив не будет работать
SAFEARRAY (short) => C # Массив short
SAFEARRAY (long) => C # Массив int
SAFEARRAY (double) => C # Массив double
Код Delphi:
function TChromswordLogic.Sample2(var array: OleVariant): HResult; stdcall;
var test: Double;
begin
Result := 1;
test := 7;
SafeArrayLock(array);
try
for i := 0 to 9 do
begin
//SafeArrayGutElement(array, i);
SafeArrayPutElement(array, i, test);
end;
finally
SafeArrayUnlock(array);
end;
end;
Код C #:
Array array = Array.CreateInstance(typeof(double), 10);
for (int i = array.GetLowerBound(0); i <= array.GetUpperBound(0); i++)
{
double val = 2.2;
array.SetValue(val, i);
}
test.Sample2(ref array);
Как, например, Echo выглядит следующим образом в C #:
void Echo(string input, ref string ouput)