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

发布于 2024-12-05 20:52:35 字数 2027 浏览 1 评论 0原文

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;

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

辞旧 2024-12-12 20:52:35

我在通过 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 等任何类型。

Delphi 代码:

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 之后并将 COM 库添加到 < strong>使用 Visual Studio 的参考

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 的更困难方法(它似乎不适用于字节,但它适用于其他数据类型):

SAFEARRAY(字节) => C# 数组将不起作用

SAFEARRAY(short) => C# 短数组

SAFEARRAY(long) => C# 数组 int

SAFEARRAY(double) => C# 双 Delphi 代码数组

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)

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文