У меня есть некоторый код 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 #, поэтому извиняюсь, если пропустил что-то очевидное!