1

I have a struct defined in a type library imported into both a Delphi 5 and a C# assembly.

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MyStruct
{
    public uint a;
    public float b;
}

MyStruct = packed record
    a: LongWord;
    b: Single;
end;

On the Delphi side I have a pointer to a C-style array of said structs which I would like to pass via COM to a C# assembly. Ideally, I'd like this to end up on the c# side as a myStruct[], but I'll take a pointer to a properly marshalled block of memory, the since the structs are all blittable.

Two ways I've tried are

void DoFoo([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] MyStruct[] fooArray, int size);
void DoBar(MyStruct[] barArray, int length);

which after being converted to a type library and imported into delphi are

procedure DoFoo(var fooArray: MyStruct; size: Integer); safecall;
procedure DoBar(barArray: PSafeArray; length: Integer); safecall;

I didn't think safe arrays worked with structs, and the other clearly isn't an array.

Any ideas/links/whatever greatly appreciated.

Spike
  • 2,016
  • 12
  • 27
  • I suppose I could treat the whole thing as a byte[], safearray it to c# and do a load of unsafe pointer stuff to it. – Spike Sep 15 '12 at 00:46

1 Answers1

0

I did, in fact, pass the structs from delphi as a safearray, which came through to c# as a byte[].

// C# interop method.
void DoFoo(byte[] myStructs); 

// Delphi SafeArray creation
size := fooNumber* sizeof(Foo);
arrayBounds.lLbound :=  0;
arrayBounds.cElements := size;
safeArray := SafeArrayCreate( varByte, 1, arrayBounds );
SafeArrayLock(safeArray);
Move(pointerToFooArray^, safeArray.pvData^, size);
SafeArrayUnlock(safeArray);
auroraDiagnostics.DoFoo(safeArray);

Then I used this solution to convert it back to the original structs.

It's a bit clunky, but it works.

Community
  • 1
  • 1
Spike
  • 2,016
  • 12
  • 27