如何用C语言重新构建Delphi中的`Record`结构?

2026-04-28 01:201阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计743个文字,预计阅读时间需要3分钟。

如何用C语言重新构建Delphi中的`Record`结构?

我在使用Delphi构建DLL,它需要与Windows API进行交互。这个DLL有一个导出函数,如下所示:function DoSomething(var MyRecord: TMyRecord): Integer; stdcall;其中,TMyRecord是我需要的记录类型,我需要在C语言环境中处理。

我正在使用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并使用ColorTranslator.ToWin32ColorTranslator.FromWin32来处理转换.

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相同.

我只是在脑海里编了这个,所以可能会有一些皱纹.

如何用C语言重新构建Delphi中的`Record`结构?

标签:Struct

本文共计743个文字,预计阅读时间需要3分钟。

如何用C语言重新构建Delphi中的`Record`结构?

我在使用Delphi构建DLL,它需要与Windows API进行交互。这个DLL有一个导出函数,如下所示:function DoSomething(var MyRecord: TMyRecord): Integer; stdcall;其中,TMyRecord是我需要的记录类型,我需要在C语言环境中处理。

我正在使用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并使用ColorTranslator.ToWin32ColorTranslator.FromWin32来处理转换.

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相同.

我只是在脑海里编了这个,所以可能会有一些皱纹.

如何用C语言重新构建Delphi中的`Record`结构?

标签:Struct