如何将字节数组从delphi传递给C#dll?

时间:2011-09-20 08:16:42

标签: c# delphi com

c#中有一个带有接受字节数组的方法的dll。

public void CheckImageForFedCompliant(byte[] image)
 { 
       LoadImage(image);

        if (_errorMessages == null)
        {
            _errorMessages = new List<String>();
        }
        _errorMessages.Clear();

        // The image did not match the tiff specification so do not try to perform other tests. 
        if (!_tiffReader.IsTiff)
        {
            _errorMessages.Add("does not match the tiff specification");
        }

        if (!_tiffReader.IsSingleStrip)
            _errorMessages.Add("is not single strip");

        if (!_tiffReader.IsSinglePage)
            _errorMessages.Add("contains more than one page");


        TestCompression();
        TestPhotometricValue();
        TestImageWidthIsValidAndPresent();
        TestImageLengthIsValidAndPresent();
        TestXandYResolutionIsValidAndPresent();
        TestResolutionUnitIsValidPresent();
        TestStripByteCountsIsPresent();
        TestStripOffsetsIsPresent();
        TestRowsPerStripIsValidAndPresent();
        TestNewSubfileTypeIsValidAndPresent();
        TestBitPerSampleIsValidAndPresent();
        TestThresholdingIsValidAndPresent();
        TestFillOrderIsValidAndPresent();
        TestOrientationIsPresent();
        TestSamplePerPixelIsValidAndPresent();
        TestT6OptionsIsValidAndPresent();

    }
 }

我在Delphi中使用的这个Dll(注册并能够成功调用dll方法)。 delphi函数具有指针和图像大小。我正在计算这两个得到字节数组, 但是当我传递它时会收到“参数不正确”这样的错误

Function TscImage.Validate (pImagePointer : Pointer; dwImageSize : Cardinal) : Boolean;
var
  ImageByteArray      : array of byte;
begin
   SetLength(ImageByteArray, dwImageSize);
   Move(pImagePointer^, ImageByteArray, dwImageSize);  
   eFedImageCompliantResult := ImagingCommonIntrop.CheckImageForFedCompliant(ImageByteArray[0]);
   //  eFedImageCompliantResult := ImagingCommonIntrop.CheckImageForFedCompliant(ImageByteArray); internal error E6724
   Result := true;
end;

有人可以分享一些有关此事的信息吗? 或任何建议。

1 个答案:

答案 0 :(得分:0)

我遇到类似的问题,通过 COM / OLE 接口将不同类型的数组从 C#传递到Delphi / C / C ++ 非托管代码。

这是我找到的工作:

IDL file definitions:

[
  uuid(270FB76B-8CA7-47CA-AAA-7C76F55F39A2), 
  version(1.0), 
  helpstring("Interface for Logic Object"), 
  oleautomation
]
 interface ILogic: IUnknown
{
  [
  id(0x00000065)
  ]
  HRESULT _stdcall Sample1([in] double value, [in, out] int * length, [in, out] VARIANT * bytes );
  [
  id(0x00000066)
  ]
  HRESULT _stdcall Sample2([in, out] SAFEARRAY(double) array );
  [
  id(0x00000067)
  ]
  HRESULT _stdcall Echo([in] LPWSTR input, [in, out] LPWSTR * ouput );
};

使用VARIANT的最简单方法

它适用于任何类型,如int,double等。

德尔福代码:

function TLogic.Sample1(value: Double; var length: SYSINT;
  var bytes: OleVariant): HResult; stdcall;  
  var test: Byte;
begin  
    Result := 1;
    test := 7;

    for i := 0 to length do
      bytes[i] := test;
    end;    
end;

在regsrv32.exe name-of-lib.dll之后并使用Visual Studio将COM库添加到引用

C#代码:

ILogic test = new IClassLogic(); //COM inctance of interface (counter-intuitive for C#)
byte[] bytes = new byte[100000];
object obj = (object)bytes;
test.Sample1(2.0, ref length, ref obj);

使用SAFEARRAY更难的方式(它似乎不适用于byte,但它适用于其他数据类型):

SAFEARRAY(byte)=&gt; C#数组不起作用

SAFEARRAY(短)=&gt; C#短的数组

SAFEARRAY(长)=&gt; C#Array of int

SAFEARRAY(double)=&gt; C#双重数组

德尔福代码:

function TChromswordLogic.Sample2(var array: OleVariant): HResult; stdcall;  
  var test: Double;
begin  
    Result := 1;
    test := 7;

    SafeArrayLock(array);
  try
    for i := 0 to 9 do
    begin
        //SafeArrayGutElement(array, i);
        SafeArrayPutElement(array, i, test);     
    end;
  finally
    SafeArrayUnlock(array);
  end;   
end;

C#代码:

Array array = Array.CreateInstance(typeof(double), 10);
for (int i = array.GetLowerBound(0); i <= array.GetUpperBound(0); i++)
{
    double val = 2.2;
    array.SetValue(val, i);
}
test.Sample2(ref array);

例如Echo在C#中看起来像这样:

void Echo(string input, ref string ouput)