不能通过非托管导出返回自定义类型实例(Robert Giesecke)

时间:2014-03-19 11:01:28

标签: c# delphi pinvoke

我正在使用RobertGiesecke的Unmanaged Exports Nuget包导出.NET dll函数,以便在delphi5 win32应用程序中调用它。 传递和返回标准类型(string,int ...)时,一切都运行良好。 但我尝试按照编组样本(https://sites.google.com/site/robertgiesecke/Home/uploads#TOC-Marshalling-sample)返回C#中定义的自定义类型的实例,但我无法正确访问delphi中的实例。

在Delphi中,我的代码是:

type
  TCreateSampleInstance = procedure(var sample: PSample); stdcall;

  TSample = record
    Name: WideString;
  end;
  PSample = ^TSample;

var
  sample: PSample;
  dllHandle: Cardinal;
  proc4: TCreateSampleInstance;
begin
  dllHandle := LoadLibrary('myDotNetAssembly.dll');

  if dllHandle <> 0 then
  try
    @proc4 := GetProcAddress(dllHandle, PChar('CreateSampleInstance'));
    if Assigned(proc4) then
    begin
      proc4(sample);
      // how to access sample properties ?
      Caption := sample^.Name; // Name = '' here instead of 'Test'...
    end;
  finally
    FreeLibrary(dllHandle);
  end;
end;

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

你可能有一个额外的间接层。您已经编写了一个指向记录指针的Delphi代码。我希望C#代码编组指向记录的指针。我希望这不仅仅是因为在C#中编组指向记录的指针需要花费很多精力。

我的猜测是C#代码是这样的:

public static void CreateSampleInstance(out Sample sample)

在这种情况下,你需要像这样写:

<强> C#

public struct Sample
{
    [MarshalAs(UnmanagedType.BStr)]
    string Name;
}

[DllExport]
public static void CreateSampleInstance(out Sample sample)
{
    sample.Name = "boo yah";
}

<强>的Delphi

type
  TSample = record
    Name: WideString;
  end;

procedure CreateSampleInstance(out sample: TSample); stdcall; 
  external 'myDotNetAssembly.dll';

在Delphi方面,为了简单起见,我用加载时链接编写了它。如果这是您的要求,您可以轻松适应运行时链接。