简体   繁体   中英

How to pass byte array from delphi to C# dll?

There is a dll in c# with a method that accepts byte array.

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();

    }
 }

This Dll I am using in Delphi (registered and able to call the dll method successfully). The delphi function having a pointer and size of image. I am calulation these two to get byte array, but when I am passing it getting error like "Parameter is incorrect"

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;

Can anyone share some information on this? Or any suggestion.

I had similar problems passing different kinds of arrays from C# to Delphi / C / C++ unmanaged code via COM / OLE interface.

Here's what I found working:

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 );
};

Easiest way using VARIANT :

it works with any type like int, double, etc.

Delphi code:

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;

After regsrv32.exe name-of-lib.dll and adding COM library to refrences using Visual Studio

C# code:

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);

Harder way using SAFEARRAY (it seems not working with byte but it works good with other data types):

SAFEARRAY(byte) => C# Array will not work

SAFEARRAY(short) => C# Array of short

SAFEARRAY(long) => C# Array of int

SAFEARRAY(double) => C# Array of double

Delphi code:

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# code:

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);

As for example Echo looks like this in C#:

void Echo(string input, ref string ouput)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM