C# - calling ext. DLL function containing Delphi "variant record" parameter
Posted
by CaldonCZE
on Stack Overflow
See other posts from Stack Overflow
or by CaldonCZE
Published on 2010-05-29T22:49:26Z
Indexed on
2010/05/29
22:52 UTC
Read the original article
Hit count: 297
Hello,
In external (Delphi-created) DLL I've got the following function that I need to call from C# application.
function ReadMsg(handle: longword; var Msg: TRxMsg): longword; stdcall; external 'MyDll.dll' name 'ReadMsg';
The "TRxMsg" type is variant record, defined as follows:
TRxMsg = record
case TypeMsg: byte of
1: (accept, mask: longword);
2: (SN: string[6]);
3: (rx_rate, tx_rate: word);
4: (rx_status, tx_status, ctl0, ctl1, rflg: byte);
end;
In order to call the function from C#, I declared auxiliary structure "my9Bytes" containing array of bytes and defined that it should be marshalled as 9 bytes long array (which is exactly the size of the Delphi record).
private struct my9Bytes {
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 9)]
public byte[] data;
}
Then I declared the imported "ReadMsg" function, using the "my9bytes" struct.
[DllImport("MyDll.dll")]
private static extern uint ReadMsg(uint handle, ref my9Bytes myMsg);
I can call the function with no problem... Then I need to create structure corresponding to the original "TRxMsg" variant record and convert my auxiliary "myMsg" array into this structure.
I don't know any C# equivalent of Delphi variant array, so I used inheritance and created the following classes.
public abstract class TRxMsg {
public byte typeMsg;
}
public class TRxMsgAcceptMask:TRxMsg {
public uint accept, mask;
//...
}
public class TRxMsgSN:TRxMsg {
public string SN;
//...
}
public class TRxMsgMRate:TRxMsg {
public ushort rx_rate, tx_rate;
//...
}
public class TRxMsgStatus:TRxMsg {
public byte rx_status, tx_status, ctl0, ctl1, rflg;
//...
}
Finally I create the appropriate object and initialize it with values manually converted from "myMsg" array (I used BitConverter for this).
This does work fine, this solution seems to me a little too complicated, and that it should be possible to do this somehow more directly, without the auxiliary "my9bytes" structures or the inheritance and manual converting of individual values. So I'd like to ask you for a suggestions for the best way to do this.
Thanks a lot!
© Stack Overflow or respective owner