我有一个包含此方法的 C# 库:

public void writeSimulator(byte[] data, byte nombre)

因此 SendBuff 是一个字节数组。在 Delphi 中,我导入了库,并在导入中包含以下内容:

// *********************************************************************//
// Déclaration de classe proxy de serveur OLE
// Objet serveur        : TSimulator
// Chaîne d'aide : 
// Interface par défaut : _Simulator
// DISP Int. Déf. ?     : No
// Interface événements : 
// TypeFlags            : (2) CanCreate
// *********************************************************************//
  TSimulator = class(TOleServer)
  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;
    procedure Connect; override;
    procedure ConnectTo(svrIntf: _Simulator);
    procedure Disconnect; override;
    function Equals(obj: OleVariant): WordBool;
    function GetHashCode: Integer;
    function GetType: _Type;
    procedure writeSimulator(data: PSafeArray; nombre: Byte);
    procedure readSimulator(var data: PSafeArray; nombre: Byte);

然后在我的代码中我像这样调用 writeSimulator:

MCMT2021.VoieAD.writeSimulator(PSafeArray(SendBuff), NumbyteWrite);

SendBuf 是一个字节数组。如果我不把它放进去,就会被类​​型转换抛出!!!感谢你的帮助 Michel

2

  • 2
    这与类型转换无关。您要么从 Delphi 向 C# 进行互操作调用,要么从 C# 向 Delphi 进行互操作调用(不清楚)。或者,由于评论提到了 OLE,您应该使用 COM 和 C# 而不是本机调用。这要么是一个互操作问题,要么使用了错误的技术


    – 

  • byte[] data不仅仅是字节数组或指向内存的指针。.NET 数组具有特定长度,类似于 COM 数组。事实上,将 C# 对象公开为 COM 对象要比尝试像调用 C 方法一样调用方法容易得多


    – 


最佳答案
1

PSafeArray是指向 OLE 结构的指针

您不能简单地将普通 Delphi 数组转换为PSafeArray,因为它们不是兼容类型。您需要SAFEARRAY正确创建一个 并将字节数据复制到其中。

您可以使用OLE函数创建一个SAFEARRAY,然后使用函数访问数组数据的内存块,例如:

uses
  // if you want to use SafeArrayCreateVector(), uncomment 'ActiveX'...
  ..., Ole2{, ActiveX};

var
  bounds: TSafeArrayBound;
  psa: PSafeArray;
  pdata: Pointer;
begin
  bounds.cElements := NumbyteWrite;
  bounds.lLbound := 0;
  psa := SafeArrayCreate(VT_UI1, 1, @bounds);
  // or:
  // psa := SafeArrayCreateVector(VT_UI1, 0, NumbyteWrite);
  if psa = nil then OleCheck(E_OUTOFMEMORY);
  try
    OleCheck(SafeArrayAccessData(psa, pdata));
    try
      Move(SendBuff[0], pdata^, NumbyteWrite);
    finally
      OleCheck(SafeArrayUnaccessData(psa));
    end;
    MCMT2021.VoieAD.writeSimulator(psa, NumbyteWrite);
  finally
    SafeArrayDestroy(psa);
  end;
end;

另外,Delphi 本身支持SAFEARRAY类型。在这种情况下,您可以使用 RTL 的和函数,然后使用函数提取指针,例如:PSafeArray

uses
  ..., Variants;

var
  v: Variant;
  pdata: Pointer;
begin
  v := VarArrayCreate([0,NumbyteWrite-1], varByte);
  pdata := VarArrayLock(v);
  try
    Move(SendBuff[0], pdata^, NumbyteWrite);
  finally
    VarArrayUnlock(v);
  end;
  MCMT2021.VoieAD.writeSimulator(PSafeArray(VarArrayAsPSafeArray(v)), NumbyteWrite);
end;

3

  • 好的,我找到了如何创建 SafeArray,现在我已正确接收它。我的最后一个问题是如何在 Delphi 中将 mysafeArray.pvData 指针赋予我自己的字节数组。我尝试过类似以下方法:tableau:=PbyteArray(MaSafeArray.pvData),但不起作用。


    – 


  • @michastro 抱歉,您无法让pvData成员指向您自己的内存缓冲区。pvData仅在 被锁定时才有效SAFEARRAY,并且锁定它(通过SafeArrayLock()SafeArrayAccessData())将使其pvData指向由 管理的内部缓冲区SAFEARRAY


    – 


  • 好的,谢谢,现在可以正常工作了。


    –