在C#代码中使用带有字符串[255]类型和结构的Delphi DLL

选择

我只有客户提供的API描述的DLL和文本文件(请参见下文)。我没有关于DLL的更多详细信息。我不知道Delphi版本等。

我尝试同时使用两个API函数,但未成功。通常,字符串[255]的前两个参数(PatientID和AccessionNo)很重要。我将字符串传递到该DLL的任何尝试均未提供正确的结果。我在应用程序GUI中看到随机垃圾值或字符串的一部分。我查看了该网站上的所有相关问题,并在互联网上进行了搜索,但没有找到任何对我有帮助的信息。

  1. OpenStudy函数-我为CharSet = CharSet.Ansi和Auto尝试了不同的设置,对于MarshalAs都是所有合适的值(请参见下文)。我在托管应用程序GUI文本字段中看到了垃圾随机值。

    [DllImport("Lib\\RISInterface.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "Open_Study", ExactSpelling = false)]
    
    static extern internal int OpenStudy(
    
    // try to use here and for all string fields [MarshalAs(UnmanagedType.AnsiBStr)] , LPStr, LPTStr, LPWStr, BStr, TBStr, HString 
    string PatientID,
    string AccessionNo,
    bool CloseCurrentStudy,
    bool AddToWindow,
    int SeriesRows,
    int SeriesCols,
    int PresentationMode,
    bool AutoTile,
    bool AutoLoad,
    bool RemoteExam);
    
  2. OpenStudy1函数-我填充结构并调用函数。我将PatientID和AccessionNo视为普通字符串,但PatientID缺少第一个字母,而AccessionNo缺少前两个字母。(发送:“ qwerty”,“ 12345”,请参阅:“ werty”,“ 345”)

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct TIQStudyAutomation
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
        public string PatientID;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
        public string AccessionNo;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
        public string StudyUID;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
        public string SeriesUID;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
        public string InstanceUID;
        public bool CloseCurrentStudy;
        public bool AddToWindow;
        public int SeriesRows;
        public int SeriesCols;
        public int PresentationMode;
        public bool AutoTile;
        public bool AutoLoad;
        public bool RemoteExam;
        public bool LoadFromAllSources;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
        public string ArchiveName;
    }
    
    [DllImport("Lib\\RISInterface.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "Open_Study1", ExactSpelling = false)]
    
    static extern internal int OpenStudy1(TIQStudyAutomation automationInfo);
    

================ API说明=============================== ===========

这些函数声明是Delphi代码,所有字符串引用都是Ansi字符串。

function Open_Study(PatientID, AccessionNo: PAnsiChar; CloseCurrentStudy, AddToWindow: Boolean; 
    SeriesRows, SeriesCols, PresentationMode: Integer; 
    AutoTile, AutoLoad, RemoteExam: Boolean): Integer; stdcall;
Return
    Error Code.

Remarks
    The parameters will be packed into a TIQStudyAutomation record and passed to Open_Study1.

//--------------------------------------------------------------------------------------------------

function Open_Study1(AutomationInfo: TIQStudyAutomation): Integer; stdcall;
Return
    Error Code.

Parameters
    Takes a TIQStudyAutomation record.

//--------------------------------------------------------------------------------------------------


TIQStudyAutomation = record 

  PatientID, AccessionNo, StudyUID, SeriesUID, InstanceUID: STRING[255];

  CloseCurrentStudy, AddToWindow: BOOLEAN;

  SeriesRows, SeriesCols, PresentationMode: Integer;

  AutoTile, AutoLoad, RemoteExam, LoadFromAllSources : BOOLEAN; ArchiveName: STRING[255];

end;

有什么帮助吗?

大卫·赫弗南(David Heffernan)

无需翻译记录,由于使用了Delphi短字符串,因此非常棘手。相反,您可以简单地致电Open_StudyDelphi声明为:

function Open_Study(
  PatientID: PAnsiChar; 
  AccessionNo: PAnsiChar; 
  CloseCurrentStudy: Boolean;
  AddToWindow: Boolean; 
  SeriesRows: Integer; 
  SeriesCols: Integer; 
  PresentationMode: Integer; 
  AutoTile: Boolean;
  AutoLoad: Boolean;
  RemoteExam: Boolean
): Integer; stdcall;

唯一真正的折衷是DelphiBoolean类型是1字节类型。但是C#bool默认将其编组为4字节类型,以匹配Win32类型BOOL

所以我会像这样翻译函数:

[DllImport("Lib\\RISInterface.dll", CallingConvention = CallingConvention.StdCall,
    CharSet = CharSet.Ansi, EntryPoint = "Open_Study", ExactSpelling = true)]
static extern internal int OpenStudy(
    string PatientID,
    string AccessionNo,
    [MarshalAs(UnmanagedType.U1)] bool CloseCurrentStudy,
    [MarshalAs(UnmanagedType.U1)] bool AddToWindow,
    int SeriesRows,
    int SeriesCols,
    int PresentationMode,
    [MarshalAs(UnmanagedType.U1)] bool AutoTile,
    [MarshalAs(UnmanagedType.U1)] bool AutoLoad,
    [MarshalAs(UnmanagedType.U1)] bool RemoteExam
);

至于string[255]处理起来有些棘手。该类型的大小为256。第一个字节为字符串长度,其余字节为有效负载。此有效负载是ANSI编码的8位字符的数组。并且此数组不必为空终止。

您不能自动将其编组,因为p / invoke框架不支持这种类型。我个人将声明将此类型转换为byte[]我将与元帅一起封送[MarshalAs(UnmanagedType.ByValArray, SizeConst=256)]然后,我将编写帮助程序函数以在C#字符串之间进行编组。这些将涉及到Encoding.GetString和的调用Encoding.GetBytes,请注意适当地处理字符串长度。

当然有可能,但是有点混乱。因此,我建议您尽可能避免这样做,并调用helper函数Open_Study

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章