重新创建Delphi`Record`的C#`Struct`版本 – 作为参数传入DLL
我正在使用Delphi构建DLL,它需要与
Windows API的工作方式类似.这个DLL只有一个导出函数……
function DoSomething(var MyRecord: TMyRecord): Integer; stdcall; …其中TMyRecord =我的记录我需要在C#中重新创建.如果我没有弄错,这正是标准Windows API的工作原理.此记录还包含对另一种记录类型的引用… TMyOtherRecord = record SomeDC: HDC; SomeOtherInt: Integer; end; TMyRecord = record SomeInteger: Integer; SomeColor: TColor; SomeText: PChar; SomeTextSize: Integer; MyOtherRecord: TMyOtherRecord; end; 问题第1部分: 我想看看我是否可以避免使用PChar,如果可能的话.我不希望传递超过255个字符的内容.是否有其他类型我可以使用而不需要我使用字符串大小? 问题第2部分: 我需要仔细检查我是否正确地声明了这个C#struct类,因为它需要完全匹配Delphi中声明的Record … public struct MyOtherRecord { public IntPtr SomeDC; public int SomeOtherInt; } public struct MyRecord { public int SomeInteger; public Color SomeColor; public string SomeText; public int SomeTextSize; public MyOtherRecord OtherReord = new MyOtherRecord(); } 问题第3部分: 在这种情况下,在记录(或结构内部的结构)内部记录是否安全?很确定它是,但我需要确定. 解决方法
我将假设信息从C#流向Delphi而不是其他方式,主要是因为这样在写答案时会让生活变得更轻松,而你没有说明其他情况!
在这种情况下,Delphi函数声明应该是: function DoSomething(const MyRecord: TMyRecord): Integer; stdcall; 第一点是你不能指望P / invoke marshaller处理System.Drawing.Color.将颜色声明为int并使用 PChar没什么好害怕的.您不需要具有字符串长度的字段,因为由于空终止符,长度隐含在PChar中.只需在C#结构中将字段声明为字符串,在Delphi记录中将PChar声明,并让P / invoke marshaller发挥其魔力.不要试图从Delphi写入PChar内容.那将以泪水结束.如果你想将一个字符串传递给C#代码,那么有一些方法,但我不会在这里解决它们. 内联结构完全没问题.没有什么可担心的.不要用新的分配它们.只需将它们视为值类型(它们是),如int,double等. 在适当的时候,您将需要添加StructLayout属性等,使用DllImport声明您的DLL函数,依此类推. 总而言之,我会声明你的结构如下: 德尔福 TMyOtherRecord = record SomeDC: HDC; SomeOtherInt: Integer; end; TMyRecord = record SomeInteger: Integer; SomeColor: TColor; SomeText: PChar; MyOtherRecord: TMyOtherRecord; end; function DoSomething(const MyRecord: TMyRecord): Integer; stdcall; C# [StructLayout(LayoutKind.Sequential)] public struct MyOtherRecord { public IntPtr SomeDC; public int SomeOtherInt; } [StructLayout(LayoutKind.Sequential)] public struct MyRecord { public int SomeInteger; public int SomeColor; public string SomeText; public MyOtherRecord MyOtherRecord; } [DllImport("mydll.dll")] static extern int DoSomething([In] ref MyRecord MyRecord); 我没有使用MarshalAs标记字符串,因为默认情况下将其编组为LPSTR,它与Delphi 7 PChar相同. 我只是在脑海里编了这个,所以可能会有一些皱纹. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |