c# - 如何解决从 Delphi 调用 C# dll 方法时出现的错误外部异常 E0434352
问题描述
我需要解压缩大的 gzip 文件(超过 4.5 Go)。我在使用 TDecompressionStream 的 Delphi Seattle 时遇到了一些麻烦(结果文件被截断)。
为避免此问题,我选择在 C# dll 中执行此任务并从 Delphi 调用它。
我的 C# 代码正在运行,我使用控制台应用程序对其进行了测试。我添加了 nugget 包 UnmanagedExports 并以 32 位编译 dll。
当我从 Delphi 调用我的 dll 方法时,出现此错误:“外部异常 E0434352”
我遵循此链接的建议: How to use a DLL created with C# in Delphi
但我已经有这个问题
我的 C# 代码
static public class UnZip
{
[DllExport("UngzipFile", CallingConvention.StdCall)]
public static int UngzipFile(string aFile)
{
int result = 0;
FileInfo fileInfo = new FileInfo(aFile);
using (FileStream fileToDecompress = fileInfo.OpenRead())
{
string decompressedFileName = Path.Combine(Path.GetDirectoryName(aFile), "temp.sql");
using (FileStream decompressedStream = File.Create(decompressedFileName))
{
using (GZipStream decompressionStream = new GZipStream(fileToDecompress, CompressionMode.Decompress))
{
try
{
decompressionStream.CopyTo(decompressedStream);
}
catch
{
result = 1;
}
}
}
}
return result;
}
}
我的德尔福代码
function UngzipFile(aFile : string) : Integer; stdcall; external 'UnCompress.dll';
procedure TForm1.UnzipFile(aFileName: String);
var
UnZipFileName : string;
Return : integer;
DllZipFile : PWideChar;
begin
UnZipFileName := ExtractFilePath(aFileName)+'Temp.sql';
if FileExists(UnZipFileName) then
DeleteFile(UnZipFileName);
DllZipFile := PWideChar(aFileName);
Return := UngzipFile(DllZipFile);
if Return > 0 then
raise Exception.Create('Error while uncompressing file');
end;
目前,当我从 Delphi 调用 UngzipFile 时,_我得到了外部异常 E0434352。
我希望结果 = 0 并且我的文件是解压缩的。
谢谢你的帮助。
解决方案
感谢 Rudy,我找到了解决方案。
由于字符串参数,我的 DLL 中有一个异常。我在 dll 中添加日志,我发现只有我的参数的第一个字符被 dll 占用。
这篇文章在 Delphi 中使用 C# DLL 仅使用第一个函数参数帮助我更正我的代码。
新的 C# 代码
static public class UnZip
{
[DllExport("UngzipFile", CallingConvention.StdCall)]
public static int UngzipFile([MarshalAs(UnmanagedType.LPWStr)] string aFile)
{
if (!File.Exists(aFile))
return 3;
FileInfo fileInfo;
string logFile = @"D:\Temp\logDll.log";
try
{
File.AppendAllText(logFile, aFile);
fileInfo = new FileInfo(aFile);
}
catch(Exception ex)
{
File.AppendAllText(logFile, String.Format("File : {0} || Exception : {1}",aFile,ex.Message));
return 2;
}
int result = 0;
using (FileStream fileToDecompress = fileInfo.OpenRead())
{
string decompressedFileName = Path.Combine(Path.GetDirectoryName(aFile), "temp.sql");
using (FileStream decompressedStream = File.Create(decompressedFileName))
{
using (GZipStream decompressionStream = new GZipStream(fileToDecompress, CompressionMode.Decompress))
{
try
{
decompressionStream.CopyTo(decompressedStream);
}
catch
{
result = 1;
}
}
}
}
return result;
}
}
通过在我的参数声明中添加“[MarshalAs(UnmanagedType.LPWStr)]”,可以解决问题。
谢谢鲁迪的帮助。
推荐阅读
- python - 当我有下面提到的名为 seeker 的起始节点时,如何找到与名为 target 的目标节点的距离?
- string - 如何检查字符串是否仅由 CMake 中的 ASCII 字符组成?
- ruby-on-rails - Minitest 和 Fixtures:传递正确的参数?
- c++ - 如何在动态调整大小的结构中打印所有值?C++
- python - 使用 Python 在字符串中搜索
- android - 为 iOS 和 Android 离线保存整个站点
- javascript - 无法读取 javascript 中未定义的属性“classList”
- django - Django - 如何在管理表单中设置请求?
- java - 使用模拟测试时无法注入 application.properties 中定义的@value
- javascript - 解构对象数组