gpt4 book ai didi

c# - 从 C# 调用 Delphi DLL 产生意外结果

转载 作者:太空狗 更新时间:2023-10-29 18:00:48 24 4
gpt4 key购买 nike

我有一个不是我编写的 Delphi DLL,但需要从 C# ASP.NET 3.5 应用程序调用。这是我从开发人员那里得到的函数定义:

function CreateCode(SerialID : String; 
StartDateOfYear, YearOfStartDate, YearOfEndDate, DatePeriod : Word;
CodeType,RecordNumber,StartHour,EndHour : Byte) : PChar;
external 'CreateCodeDLL.dll';

这是我的 C# 代码:

[DllImport( "CreateCodeDLL.dll", 
CallingConvention = CallingConvention.StdCall,
CharSet=CharSet.Ansi)]
public static extern IntPtr CreateCode( string SerialID,
UInt16 StartDateOfYear,
UInt16 YearOfStartDate,
UInt16 YearOfEndDate,
UInt16 DatePeriod,
Byte CodeType,
Byte RecordNumber,
Byte StartHour,
Byte EndHour);

最后,我调用这个方法:

//The Inputs 
String serialID = "92F00000B4FBE";
UInt16 StartDateOfYear = 20;
UInt16 YearOfStartDate = 2009;
UInt16 YearOfEndDate = 2009;
UInt16 DatePeriod = 7;
Byte CodeType = 1;
Byte RecordNumber = 0;
Byte StartHour = 15;
Byte EndHour = 14;

// The DLL call
IntPtr codePtr = CodeGenerator.CreateCode(serialID, StartDateOfYear,
YearOfStartDate, YearOfEndDate, DatePeriod, CodeType,
RecordNumber, StartHour, EndHour);

// Take the pointer and extract the code in a string
String code = Marshal.PtrToStringAnsi(codePtr);

每次我重新编译这段代码并运行它时,它都会返回一个不同的值。预期值是由数字组成的 10 位代码。返回值实际上是12位数字。

最后一条重要信息是我有一个测试 .EXE,它有一个 GUI,可以让我测试 DLL。使用 .EXE 的每个测试都会返回相同的 10 位数字(预期结果)。

因此,我必须相信我错误地声明了对 DLL 的调用。想法?

最佳答案

Delphi 默认使用所谓的 fastcall 调用约定。这意味着编译器会尝试将参数传递给 CPU 寄存器中的函数,并且仅当参数多于空闲寄存器时才使用堆栈。例如,Delphi 使用 (EAX, EDX, ECX) 作为函数的前三个参数。
在您的 C# 代码中,您实际上使用的是 stdcall 调用约定,它指示编译器通过堆栈传递参数(以相反的顺序,即先推送最后一个参数)并让被调用者清理堆栈。
相比之下,C/C++ 编译器使用的 cdecl 调用会强制调用者清理堆栈。
只要确保您在双方都使用相同的调用约定即可。 Stdcall 之所以被广泛使用,是因为它几乎可以在任何地方使用,并且每个编译器都支持它(Win32 API 也使用此约定)。
请注意,无论如何,.NET 都不支持 fastcall

关于c# - 从 C# 调用 Delphi DLL 产生意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/517944/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com