繁体   English   中英

从C#asp.net调用Delphi XE6 Unicode dll

[英]Call Delphi XE6 unicode dll from C# asp.net

在打开主题搜索主题之前,我的错误仍然存​​在,我在Delphi XE6 64x中创建了一个dll,如下所示:

function GeraChave(Action : PAnsiChar; StrCrip : PAnsiChar; Cnpj : PAnsiChar; idPC: PAnsiChar): PAnsiChar; stdcall;
var
 KeyLen : Integer;
 KeyPos : Integer;
 OffSet : Integer;
 Dest, Key : String;
 SrcPos : Integer;
 SrcAsc : Integer;
 TmpSrcAsc : Integer;
 Range, I : Integer;
 matKey : Array[0..7] of String;
begin
  if (StrCrip = '') Then
  begin
    Result:= '';
    Exit;
  end;

  for I := 0 to 8 do
    matKey[I] := Copy(idPC, I, 1);

  Key := 'A#%tgNh*'+ matKey[0] +'UJklo'+ matKey[1] + 'O' + cnpj + 'O' +
         '798DS'+ matKey[2] +'Cea'+ matKey[3] +'SEc%7*I'+ matKey[4] +'u@Ed#'+
         matKey[5] +'f$f'+ matKey[6] +'%g&j-9'+ matKey[7] +'sc';

  Dest := '';
  KeyLen := Length(Key);
  KeyPos := 0;
  SrcPos := 0;
  SrcAsc := 0;
  Range := 256;

  if (Action = UpperCase('C')) then
  begin
    Randomize;
    OffSet := Random(Range);
    Dest := Format('%1.2x',[OffSet]);
    for SrcPos := 1 to Length(StrCrip) do
    begin
      SrcAsc := (Ord(StrCrip[SrcPos]) + OffSet) Mod 255;
      if KeyPos < KeyLen then KeyPos := KeyPos + 1 else KeyPos := 1;

      SrcAsc := SrcAsc Xor Ord(Key[KeyPos]);
      Dest := Dest + Format('%1.2x',[SrcAsc]);
      OffSet := SrcAsc;
    end;
  end
  Else if (Action = UpperCase('D')) then
  begin
    OffSet := StrToInt('$' + copy(StrCrip,1,2));
    SrcPos := 3;
    repeat
      SrcAsc := StrToInt('$' + copy(StrCrip,SrcPos,2));
      if (KeyPos < KeyLen) Then KeyPos := KeyPos + 1 else KeyPos := 1;
      TmpSrcAsc := SrcAsc Xor Ord(Key[KeyPos]);
      if TmpSrcAsc <= OffSet then TmpSrcAsc := 255 + TmpSrcAsc - OffSet
      else TmpSrcAsc := TmpSrcAsc - OffSet;
      Dest := Dest + Chr(TmpSrcAsc);
      OffSet := SrcAsc;
      SrcPos := SrcPos + 2;
    until (SrcPos >= Length(StrCrip));
  end;

 Result := PAnsiChar(Dest);
end;

 Exports
 GeraChave;

 begin
end.

我的C#.NET代码如下所示:

public partial class _Default : System.Web.UI.Page
{

    [DllImport(@"H:\FTP\HOME\Web\testes\dllDelphi\Bin\DllChave.dll", 
               CallingConvention = CallingConvention.StdCall,
               CharSet = CharSet.Ansi)]

    public static extern string GeraChave(string xAction, string StrCrip, string Cnpj, string idPC);

    protected void Page_Load(object sender, EventArgs e)
    {
        string str = "A75BD3FD" + "|15/12/2016|" + "04564521020004";
        string xTp = "C";
        string Cnpj = "04564521020004";
        string IDPC = "A75BD3FD";
        string xRes = "";

        xRes = GeraChave(xTp, str, Cnpj, IDPC);

    }
}

当我调用DLL时出现错误“用户代码未处理BadImageFormatException”

谢谢!

BadImageFormatException通常指示位数不匹配。 您的Delphi模块是64位,而C#模块是32位,反之亦然。

您还有其他问题。 至少以下内容:

  • 您将UTF-16 UnicodeString字符串UnicodeStringPAnsiChar 那个演员是不正确的。
  • 您返回一个局部变量的地址。 函数返回时,局部变量超出范围。 因此,您将返回一个指向无效内存的指针。 您需要找到另一种返回该缓冲区的方法。
  • 您的C#代码假定返回的值是通过对CoTaskMemAlloc的调用分配的。 因此,它将在您返回的指针上调用CoTaskMemFree ,这显然是错误的。 但是,当您解决上述问题时,该问题将解决。

我可能WideString字符串作为WideString输出参数返回,并与C#端的UnmanagedType.BStr匹配: 为什么不能将WideString用作互操作的函数返回值? 这样,被调用方可以分配字符串,而调用方可以取消分配。

我这样决定:

在德尔斐

function GeraChave(xAction : PChar; StrCrip : PChar; Cnpj : PChar; idPC: PChar; Saida : PChar; len : Integer): Integer; stdcall;
begin
 StrLCopy(Saida, PChar(Dest), len);
 Result := 1;
end;

在C#上

public static extern int GeraChave(string xAction, string StrCrip, string Cnpj, string idPC, StringBuilder Saida, int len);
    StringBuilder str = new StringBuilder(256);
    int retval = GeraChave(xTp, strCrip, Cnpj, IDPC, str, str.Capacity);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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