【问题标题】:How to pass byte array from delphi to C# dll?如何将字节数组从delphi传递到C# dll?
【发布时间】:2011-11-20 21:03:56
【问题描述】:

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;

谁能分享这方面的一些信息? 或任何建议。

【问题讨论】:

  • 请显示您的确切 C# 代码。你想调用 C DLL 还是 Delphi 函数?
  • 您正在尝试从非托管代码调用托管程序集?这个托管程序集是公开为 COM 对象还是什么?
  • @weismat ... C# 代码运行良好,但我担心的只是在 Delphi 中传递正确的参数
  • @DarinDimitrov ya 它被公开并注册为程序集......其他方法是accesseble ..
  • 可能是this 一些亮点

标签: c# delphi com


【解决方案1】:

我在通过 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 之后,将 COM 库添加到 使用 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(byte) => C# 数组不起作用

SAFEARRAY(short) => C# 短数组

SAFEARRAY(long) => C# 数组 int

SAFEARRAY(double) => 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多