C#Pinvoke Delphi ShortString System.AccessViolationException

时间:2018-08-20 17:55:05

标签: c# asp.net delphi pinvoke

我的客户刚给我发送了一个delphi dll,供我的asp.net应用程序使用,下面是dll的签名:

function GerarChave(pChave: ShortString; pData: ShortString; pAcao: ShortString): PAnsiChar; stdcall;

我该怎么称呼它?我已经尝试过

[DllImport("CEIINT.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "GerarChave")]
    public static extern string GerarChave([MarshalAs(UnmanagedType.BStr)]string pChave, [MarshalAs(UnmanagedType.BStr)]string pData, [MarshalAs(UnmanagedType.BStr)]string pAcao);

string chave = "ABC123";
string data = "19/09/2019";
string acao = "0";
GerarChave(chave, data, acao);

但是我总是会收到一个System.AccessViolationException错误,提示:

  

System.AccessViolationException ...尝试读取或写入受保护的内存。这通常表明其他内存已损坏

有人可以帮我吗?预先感谢!

1 个答案:

答案 0 :(得分:3)

就像大卫·赫弗南(David Heffernan)所说的那样,您应该尝试回到客户那里来请求具有更多可互操作类型的DLL。

如果没有其他选择,您可以尝试手动进行转换,首先将签名更改为字节数组:

[DllImport("CEIINT.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "GerarChave")]
public static extern string GerarChave(
  [MarshalAs(UnmanagedType.ByValArray, SizeConst=256)] byte[] pChave, 
  [MarshalAs(UnmanagedType.ByValArray, SizeConst=256)] byte[] pData, 
  [MarshalAs(UnmanagedType.ByValArray, SizeConst=256)] byte[] pAcao);

然后定义以下方法将字符串转换为Delphi ShortString:

public byte[] GetDelphiShortString(string str)
{
  var bytes = new byte[256];
  bytes[0] = (byte)Encoding.Default.GetBytes(str, 0, str.Length, bytes, 1);
  return bytes;
}

最后,您应该可以通过以下方式调用Delphi函数:

GerarChave(GetDelphiShortString(chave), GetDelphiShortString(data), GetDelphiShortString(acao));