C#调用Delphi DLL,返回结构中的结构

C#调用Delphi DLL,返回结构中的结构,c#,delphi,pinvoke,C#,Delphi,Pinvoke,还有一个Delphi互操作问题 我有一个Delphi代码: library DelphiDll; uses Dialogs, SysUtils, Classes; type TestEnum = (teOne, teTwo); TTestRecord = record end; TTestType = record MyTestRecords: array [1..255] of TTestRecord; MyTes

还有一个Delphi互操作问题

我有一个Delphi代码:

library DelphiDll;

uses
  Dialogs,
  SysUtils,
  Classes;

  type
    TestEnum = (teOne, teTwo);

    TTestRecord = record
    end;

    TTestType = record
      MyTestRecords: array [1..255] of TTestRecord;
      MyTestEnum: TestEnum;
    end;

  {$R *.res}

  function DllFunction(var testType: TTestType): Boolean stdcall; export;

  begin
    testType.MyTestEnum := teTwo;

    Result := True;
  end;

  exports DllFunction;

  begin
  end.
这个C#代码:

当我运行C#代码时,testType.MyTestEnum的控制台输出总是枚举值1,即使在Delphi代码中它被明确设置为2

现在,如果我简单地从使用TestType结构中的TestRecord结构数组改为使用简单的整数数组,那么一切都很好


为什么整数数组可以工作,而结构数组却不能工作?

自从我使用Delphi(如'98年)以来,已经有整整一段时间了,但是,我记得,Delphi中的枚举是1字节数。c#中的枚举是整数(32位)

因此,您可以尝试将c#enum定义为

enum TestEnum: byte {One, Two}

这并没有解释它是如何处理int数组的。我唯一能想到的另一件事是确保c#enum的值与Delphi enum的值完全匹配(所以使用teOne,teTwo),但是因为我们实际上是在讨论一个整数/字节,我看不出这有什么关系。

主要问题是
t目录中没有定义任何内容。C代码将其封送为大小为1的字段。Delphi编译器认为大小为0。因此,这两种结构之间存在不匹配。对于
Marshal.SizeOf(typeof(TestType))
,C代码返回260,而对于
SizeOf(TTestType)
,Delphi编译器返回8

在实际代码中,可能会有一些实际的内容在该记录中,当您这样做时,一切都将开始工作


请注意,@JMarsch和@kenwhite也是有效的观点。您需要确保正确封送枚举,并且
struct
布局匹配。由于结构的填充方式,您可能不需要对枚举编组做任何处理就可以逃脱,但您也可能同样不走运

您需要在Delphi代码中设置枚举大小。Delphi将使其尽可能小,但.NET端需要
int
。在枚举声明之前向代码中添加以下内容:

{$MINENUMSIZE 4}   // can also use {$Z4} but it's not clear later when
                   // you're trying to maintain the code.
                   // Or you can use {$Z-} and {$Z+}, for
                   // {$Z1} and {$Z4} respectively

// Your enum declaration

{$MINENUMSIZE 1}

看看我的答案。虽然这个问题是相关的,但房间里有一个更大的大象。我当时的工作假设是海报知道没有内容的记录不起作用,并且出于解释目的,这是模拟代码。事实上,如果不是这样,并且海报试图在真实代码中使用无内容记录,那将是一头更大的大象。(事实上,重新阅读文章下面的文字,我想你已经明白了——我认为它可能是真实的代码,如“更改…使用简单的整数数组”所示。捕捉得很好,你的答案为+1。)我确实知道这一点,但我对枚举有着如此狭隘的看法,以至于我看不到正摆在我面前的是什么。我和你的想法是一样的,但是,由于空记录问题,这并没有解决我的问题。我只是无法摆脱我的一个思路。不过,谢谢你的帮助!你曾经有过这样的一天,你只是陷入了思维定势,似乎无法摆脱。我给出的代码是真实代码的精简示例,但我没有注意到这样一个事实,即我的精简代码(带有空记录)会导致这样一个问题。再次感谢所有的评论。下一次我将更加关注。我还认为在c#而不是Delphi中如何处理枚举类型肯定存在一个问题。这实际上是一个我忽略的简单得多的问题。空记录一直是罪魁祸首。不过,谢谢你的帮助。
{$MINENUMSIZE 4}   // can also use {$Z4} but it's not clear later when
                   // you're trying to maintain the code.
                   // Or you can use {$Z-} and {$Z+}, for
                   // {$Z1} and {$Z4} respectively

// Your enum declaration

{$MINENUMSIZE 1}