1

I'm new to vb.net and trying to call Delphi Dll that returns a record. If I put three integers in struct it works when I try something like the following code I get "Method's type signature is not PInvoke compatible".. Any ideas off why I cant add Byte Array or even if I add boolean it fails.

Public Structure SysInfo
    Public iPrtRes As Integer
    Public iMaxRips As Integer
    Public iUnits As Integer
    Public str As Byte()
End Structure

<DllImport("C:\project2.DLL", CallingConvention:=CallingConvention.Cdecl)>
Public Function getsysinfoF() As SysInfo
End Function

Dim theSysInfoRec As SysInfo
ReDim theSysInfoRec.str(255)

theSysInfoRec = getsysinfoF()

Delphi

type
  SysInfo = record
    iPrtRes: Integer;
    iMaxRips: Integer;
    iUnits: Integer;
    str: array[0..255] of Byte;
  end;

function getsysinfoF() : SysInfo; cDecl
begin
  result.iPrtRes := 400;
  result.iMaxRips := 300;
  result.iUnits := 200;
  result.str[0] := $ff;
end;

Found solultion in Passing record as a function result from Delphi DLL to C++

Community
  • 1
  • 1

1 Answers1

3

.NET managed arrays are different from unmanaged arrays in other lanuages. You need to tell PInvoke how to marshal the array field of the struct, and that depends on how the DLL allocates and manages that array in the first place. Is it a C-style array? A Delphi-style dynamic array? An ActiveX/COM SafeArray? That kind of information needs to be included in the PInvoke declaration of the struct on the .NET side using the MarshalAs attribute (obviously, Delphi-style dynamic arrays are not supported by .NET).

Refer to MSND for more details:

Default Marshaling for Arrays

MarshalAsAttribute Class

Update: For example:

Delphi:

type
  SysInfo = record
    iPrtRes: Integer;
    iMaxRips: Integer;
    iUnits: Integer;
    str: array[0..255] of Byte;
  end;

.NET:

Public Structure <StructLayout(LayoutKind.Sequential)> SysInfo
    Public iPrtRes As Integer
    Public iMaxRips As Integer
    Public iUnits As Integer
    <MarshalAs(UnmanagedType.ByValArray, SizeConst := 256)>
    Public str() As Byte
End Structure
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Delphi fixed length of 256 that's why I ReDim struct array to 255 – Randol Berry May 17 '13 at 22:29
  • With suggested Structure I get Identifier Expected at first less than symbol – Randol Berry May 20 '13 at 14:00
  • @RandolBerry I fixed the syntax, but the question is still incomplete since you have not told us what the struct is. – David Heffernan May 20 '13 at 14:33
  • I finished fixing the syntax (I think) by moving before Public and still get same error – Randol Berry May 20 '13 at 14:53
  • I'm not a .NET developer myself, but what I posted was copy/pasted from Microsoft's own VB.NET examples for array marshaling, so I would expect the syntax to compile correctly. – Remy Lebeau May 20 '13 at 15:05
  • Thank all of you for your help. Have solution for Delphi function return unsure where that leaves .net still don't know if you can get a complicated structure returned from dll function call. – Randol Berry May 20 '13 at 15:21
  • What is more likely a problem is differences in how Delphi vs .NET pass a record as a return value. You may need to change your Delphi function to pass the record as an output parameter instead of the result value. – Remy Lebeau May 20 '13 at 19:18
  • Yes close to what the solution was see last edit the previous question says delphi returns record from function as var parameter so I just called the delphi function as A Sub with ByRef in .net – Randol Berry May 20 '13 at 20:10