如何从C#调用Delphi DLL(方法的类型签名不是PInvoke兼容错误)?

时间:2019-03-12 13:25:42

标签: c# delphi dll

我有一些Delphi代码,当前正在调用DLL(也用Delphi编写)。这是Delphi代码:

    TDLLDataHeader = record
        s                   : string[255];
        i                   : integer;
        stage               : integer;
        number_of_fields    : integer;
        sample_code         : string[255];
        comment             : string[255];
    end;

    TPassword_rec = record
        level               : byte;
        User_ID             : string[20];
        Signature           : string[80];
    end;

    TField_result  = packed record        {Packed added to make size compatible with Delphi4}
        area                        : double;
        count                       : longint;
        frame_area                  : double;
        perimeter                   : double;  { currently 0}
        total_object_grey_level     : comp;
        total_framed_grey_level     : comp;
        pixel_area                  : comp;
        pixel_frame_area            : comp;
        mean_object_grey_level      : double;
        mean_framed_grey_level      : double;
        no_of_excluded_objects      : longint;
        ppm                         : double;
        total_ppm                   : double;
        ppm_squared                 : double;
    end;

    Tfeature_summary  = packed record  {Packed added to make size compatible with Delphi4}
        total_eba              : double;
        eba_ppm                : double;
        eba_ppm_squared        : double;
        total_object_area      : double;
        total_perimeter        : double;
        total_grey_level       : longint;
        ppm                    : double;
        total_ppm              : double;
        ppm_squared            : double;
    end;

    Tshortmeasurement   = record
        sample_code              : string[255];
        comment                  : string[255];
        datetime                 : Tdatetime;
        measured_by              : string[20];
        dilution                 : double;
        calibration_factor_used  : double;
        field                    : Tfield_result;
        feature                  : Tfeature_summary;
        detection_mode           : integer; {25/8/00 detection settings added to measurement data}
        straight_threshold       : byte;
        matrix_threshold         : byte;
        matrix_size              : byte;
        Count_per_plate          : integer;
    end;

procedure GetDLLData_header(var Aheaderdata : PDllDataHeader); stdcall; external 'remote.dll' name 'GetDLLData';
          { reads global data pointer back fronm the dll}
function get_data : Tshortmeasurement; stdcall; external 'remote.dll' name 'get_data';
function get_macro_status : byte; stdcall; external 'remote.dll' name 'get_macro_status';
function send_msg_to_host(lparam,wparam : longint) : longint; stdcall; external 'remote.dll' name 'send_msg_to_host';
function get_no_of_measurements : integer; stdcall; external 'remote.dll' name 'get_no_of_measurements';

进一步在Delphi代码中调用get_data:

var
    Temp_data : Tshortmeasurement;
begin
    temp_data := get_data;
end;

我试图在C#中重新创建此代码,但出现“方法的类型签名不是PInvoke兼容错误”。

这是我的C#代码:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct TField_result
{
    //area                        : double;
    public double area;
    //count                       : longint;
    public int count;
    //frame_area                  : double;
    public double frame_area;
    //perimeter                   : double;  { currently 0}
    public double perimeter;
    //total_object_grey_level     : comp;
    public double total_object_grey_level;
    //total_framed_grey_level     : comp;
    public double total_framed_grey_level;
    //pixel_area                  : comp;
    public double pixel_area;
    //pixel_frame_area            : comp;
    public double pixel_frame_area;
    //mean_object_grey_level      : double;
    public double mean_object_grey_level;
    //mean_framed_grey_level      : double;
    public double mean_framed_grey_level;
    //no_of_excluded_objects      : longint;
    public int no_of_excluded_objects;
    //ppm                         : double;
    public double ppm;
    //total_ppm                   : double;
    public double total_ppm;
    //ppm_squared                 : double;
    public double ppm_squared;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct TFeature_summary
{
    //total_eba              : double;
    public double total_eba;
    //eba_ppm                : double;
    public double eba_ppm;
    //eba_ppm_squared        : double;
    public double eba_ppm_squared;
    //total_object_area      : double;
    public double total_object_area;
    //total_perimeter        : double;
    public double total_perimeter;
    //total_grey_level       : longint;
    public int total_grey_level;
    //ppm                    : double;
    public double ppm;
    //total_ppm              : double;
    public double total_ppm;
    //ppm_squared            : double;
    public double ppm_squared;
}


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Tshortmeasurement
{
    //sample_code              : string[255];
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
    public string sample_code;
    //comment                  : string[255];
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
    public string comment;
    //datetime                 : Tdatetime;
    public double datetime;
    //measured_by              : string[20];
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string measured_by;
    //dilution                 : double;
    public double dilution;
    //calibration_factor_used  : double;
    public double calibration_factor_used;
    //field                    : Tfield_result;
    public TField_result field;
    //feature                  : Tfeature_summary;
    public TFeature_summary feature;
    //detection_mode           : integer;
    public int detection_mode;
    //straight_threshold       : byte;
    public byte straight_threshold;
    //matrix_threshold         : byte;
    public byte matrix_threshold;
    //matrix_size              : byte;
    public byte matrix_size;
    //Count_per_plate          : integer;
    public int Count_per_plate;
}


class Program
{


    [DllImport("remote.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern UIntPtr send_msg_to_host(
        IntPtr lParam,
        UIntPtr wParam
    );
    [DllImport("remote.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern int get_no_of_measurements();

    [DllImport("remote.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)]
    public static extern Tshortmeasurement get_data();

    static void Main(string[] args)
    {
        int n = get_no_of_measurements();
        get_data();
        Console.WriteLine(n.ToString());
        Console.ReadLine();
    }
}

对get_no_of_measurements的调用工作正常,但是对get_data的调用导致前面提到的错误。我研究了“编组”,我认为这一定是原因,可能与TFeature_summary和TField_result结构有关。我对C#还是很陌生,所以如果我错过了明显的事情,我深表歉意!

0 个答案:

没有答案