使用Delphi的stuct数组和字符串在C# [英] Using Delphi's stuct arrays and strings in C#

查看:322
本文介绍了使用Delphi的stuct数组和字符串在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图调用已在德尔福以下面的方式创建一个方法:

I've been trying to invoke a method that have been created in Delphi in the following way:

 function _Func1(arrParams: array of TParams): Integer;stdcall;    

 type 
   TParams = record
   Type: int;
   Name: string;
   Amount : Real;
 end;



我的代码是:

My code is:

[DllImport("some.dll", EntryPoint = "_Func1", CallingConvention = CallingConvention.StdCall)]
public static extern int Func(
  [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct)] TParams[] arrParams)

和的结构是:

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct TParams
{
  public int Type;
  [MarshalAs(UnmanagedType.AnsiBStr)]
  public string Name;
  public double Amount;
}

当我调用这个方法,我得到的错误:
不能元帅场'名称'类型'TParams:无效的托管/非托管类型组合(字符串字段必须LPSTR,LPWSTR,BSTR或成对ByValTStr)

When I am calling this method I'm getting the error: Cannot marshal field 'Name' of type 'TParams': Invalid managed/unmanaged type combination (String fields must be paired with LPStr, LPWStr, BStr or ByValTStr).

。不过这些都不组合的作品,如德尔福的字符串,其长度为前缀,这是安思肯定(我与其他字符串参数尝试过)。有没有人有一个线索如何解决此问题?

However none of those combinations works, as Delphi's strings are prefixed with its length and it is Ansi for sure (I've tried it with other string parameters). Does anyone have a clue how to solve this?

推荐答案

有两个主要问题,这一点,使用开放数组和使用的德尔福字符串

There are two main problems with this, use of open arrays and use of Delphi string.

打开阵列

德尔福开放数组被传递一个指向数组的第一个元素和一个额外的参数,指定了最后一个项目的索引, Delphi中的术语实现。欲了解更多信息,请参阅的这个答案

Delphi open arrays are implemented by passing a pointer to the first element of the array and an extra parameter specifying the index of the last item, high in Delphi terminology. For more information see this answer.

Delphi字符串

C#的编组不能与德尔福字符串互操作。德尔福字符串是私有类型,只在内部使用一个Delphi模块。相反,你应该使用一个空终止字符串, PAnsiChar

The C# marshaller cannot interop with a Delphi string. Delphi strings are private types, only to be used internally to a Delphi module. Instead you should use a null-terminated string, PAnsiChar.

全部放在一起,你可以写这样的:

Putting it all together you can write it like this:

德尔福

type 
  TParams = record
    _Type: Integer;//Type is a reserved word in Delphi
    Name: PAnsiChar;
    Amount: Double;
  end;

function Func(const arrParams: array of TParams): Integer; stdcall;



C#

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct TParams
{
  public int Type;
  public string Name;
  public double Amount;
}

[DllImport("some.dll")]
public static extern int Func(TParams[] arrParams, int high);

TParams[] params = new TParams[len];
...populate params
int retval = Func(params, params.Length-1);

这篇关于使用Delphi的stuct数组和字符串在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆