【发布时间】:2016-06-01 08:40:20
【问题描述】:
我只有来自客户的 DLL 和 API 描述文本文件(见下文)。我没有关于 DLL 的更多详细信息。我不知道 Delphi 版本等。
我尝试使用这两个 API 函数但没有成功。通常 string[255] 的前两个参数(PatientID 和 AccessionNo)很重要。我将字符串传递给该 DLL 的任何尝试都不会提供正确的结果。我在应用程序 GUI 中看到随机垃圾值或部分字符串。我查看了该网站上的所有相关问题并在互联网上进行了搜索,但没有找到任何对我有帮助的内容。
-
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); -
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;
有什么帮助吗?
【问题讨论】:
-
@ZENsan 这里还有更多。
string[255]需要一些编组。 -
大卫,你能澄清一下“string[255] 需要一些编组”是什么意思吗?
-
嗯,该类型的大小为 256。第一个字节是长度,从 0 到 255。其余字节是组成字符串的 ANSI 字符。我不相信字符串一定是空终止的。所以你所有的编组都是错误的。我会将其作为
byte[]编组为长度为 256 的ByValArray。我会编写辅助方法在 C# 字符串和 Delphi 短字符串string[255]之间移动。 -
另一个问题是德尔福
Boolean。那是一个1字节的类型。您需要将其编组为UnmanagedType.U1IIRC。我真的无法详细写出所有这些的答案,因为这将是一个非常长的答案,而且我没有时间。感觉就像我正在为您编写整个代码。无论如何,我希望这两个指针有所帮助!