Calling a Delphi DLL from C# produces unexpected r

2019-02-13 09:47发布

I have a Delphi DLL that I did not write, but need to call from a C# ASP.NET 3.5 app. Here is the function definition I got from the developers:

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

And here is my C# code:

[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);

And finally, my call to this method:

//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);  

Every time I re-compile this exact code and run it, it returns a different value. The expected value is a 10-digit code comprised of numbers. The returned value is actually 12 digits.

The last important piece of information is that I have a test .EXE that has a GUI that allows me to test the DLL. Every test using the .EXE returns the same 10-digit number (the expected result).

So, I have to believe that I have declared my call to the DLL incorrectly. Thoughts?

标签: c# delphi dll
7条回答
迷人小祖宗
2楼-- · 2019-02-13 10:21

jn is right. The function prototype, as given, cannot be easily called directly from C# as long as it is in Delphi's register calling convention. You either need to write a stdcall wrapper function for it - perhaps in another DLL if you don't have source - or you need to get the people who maintain the function to change its calling convention to stdcall.

Update: I also see that the first argument is a Delphi string. This isn't something that C# can supply either. It should be a PChar instead. Also, it's important to be clear about whether the function is Ansi or Unicode; if the DLL is written with Delphi 2009 (or later), then it is Unicode, otherwise it is Ansi.

查看更多
登录 后发表回答