我希望有人能帮助我解决我目前遇到的问题。我们有很多Delphi遗留代码,需要将我们的一些Delphi应用程序转换为C#。将非托管dll的Delphi代码转换为C#
我目前正在努力的遗留代码是从第三方应用程序的非COM DLL调用函数。
下面是C语言风格的报头和数据结构,用于为特定的功能:
/*** C Function AwdApiLookup ***/
extern BOOL APIENTRY AwdApiLookup(HWND hwndNotify, ULONG ulMsg,
BOOL fContainer, CHAR cObjectType,
SEARCH_CRITERIA* searchCriteria,
USHORT usCount, USHORT usSearchType,
VOID pReserved);
/*** C Struct SEARCH_CRITERIA ***/
typedef struct _search_criteria
{
UCHAR dataname[4];
UCHAR wildcard;
UCHAR comparator[2];
UCHAR datavalue[75];
} SEARCH_CRITERIA;
在我们的Delphi代码,我们已转换的上述功能和结构为:
(*** Delphi implementation of C Function AwdApiLookup ***)
function AwdApiLookup(hwndNotify: HWND; ulMsg: ULONG; fContainer: Boolean;
cObjectType: Char; pSearchCriteria: Pointer; usCount: USHORT;
usSearchType: USHORT; pReserved: Pointer): Boolean; stdcall;
external 'AWDAPI.dll';
(*** Delphi implementation of C Struct SEARCH_CRITERIA ***)
TSearch_Criteria = record
dataname: array [0..3] of char;
wildcard: char;
comparator: array [0..1] of char;
datavalue: array [0..74] of char;
end;
PSearch_Criteria = ^TSearch_Criteria;
和我们在Delphi中称为上述代码的方式是:
AwdApiLookup(0, 0, true, searchType, @criteriaList_[0],
criteriaCount, AWD_USE_SQL, nil);
其中criteriaList被定义为
criteriaList_: array of TSearch_Criteria;
在说完之后,我们现在可以看看C#代码,我无法工作。我确信我在这里做错了什么,或者我的C头没有被正确翻译。我的项目没有正确编译,但是当函数被调用时,我得到一个“FALSE”值,这表明该函数在DLL中没有正确执行。
我的C#代码迄今:
/*** C# implementation of C Function AwdApiLookup ***/
DllImport("awdapi.dll", CharSet = CharSet.Auto)]
public static extern bool AwdApiLookup(IntPtr handle, ulong ulMsg,
bool fContainer, char cObjectType,
ref SearchCriteria pSearchCriteria,
ushort usCount, ushort usSearchType,
Pointer pReserverd);
/*** C# implementation of C Struct SEARCH_CRITERIA ***/
[StructLayout(LayoutKind.Sequential)]
public struct SearchCriteria
{
private readonly byte[] m_DataName;
private readonly byte[] m_Wildcard;
private readonly byte[] m_Comparator;
private readonly byte[] m_DataValue;
public SearchCriteria(string dataName, string comparator, string dataValue)
{
m_DataName = Encoding.Unicode.GetBytes(
dataName.PadRight(4, ' ').Substring(0, 4));
m_Wildcard = Encoding.Unicode.GetBytes("0");
m_Comparator = Encoding.Unicode.GetBytes(
comparator.PadRight(2, ' ').Substring(0, 2));
m_DataValue = Encoding.Unicode.GetBytes(
dataValue.PadRight(75, ' ').Substring(0, 75));
}
public byte[] dataname { get { return m_DataName; } }
public byte[] wildcard { get { return m_Wildcard; } }
public byte[] comparator { get { return m_Comparator; } }
public byte[] datavalue { get { return m_DataValue; } }
}
我的C#呼叫到C#函数看起来像这样
var callResult = UnsafeAwdApi.CallAwdApiLookup(IntPtr.Zero, 0, true, 'W',
ref searchCriteria[0], criteriaCount,
66, null);
其中searchCriteria和criteriaCount被定义为
List<SearchCriteria> criteriaList = new List<SearchCriteria>();
var searchCriteria = criteriaList.ToArray();
var criteriaCount = (ushort)searchCriteria.Length;
和添加data to searchCriteria:
public void AddSearchCriteria(string dataName, string comparator, string dataValue)
{
var criteria = new SearchCriteria();
criteria.DataName = dataName;
criteria.Wildcard = "0";
criteria.Comparator = comparator;
criteria.DataValue = dataValue;
criteriaList.Add(criteria);
}
就像我说过的,我的代码编译正确,但是当函数执行时,它返回“FALSE”,不应该如此,因为Delphi函数确实使用完全相同的输入返回数据。
我知道我肯定在这里做错了什么,我尝试了几件事,但似乎没有任何工作。
任何援助或在正确的方向微调将不胜感激。
谢谢,Riaan
'指针pReserverd' - 你的意思是'IntPtr'? – 2009-11-27 07:30:40
我不确定。 C++ API将其作为VOID pReserved,并且可以工作的Delphi代码将其定义为指针pReserved。 – Riaan 2009-11-29 09:20:23