Hi.
I hope someone can assist me with the problem I'm currently experiencing. We have a lot of Delphi legacy code, and need to convert some of our Delphi applications to C#.
The legacy code I'm currently struggling with is that of calling a function from a 3rd party application's non-COM DLL.
Here is the C-style header and struct used for the specific function:
/*** 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;
In our Delphi code, we have converted the above function and structure as:
(*** 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;
and the way we call the above mentioned code in Delphi is:
AwdApiLookup(0, 0, true, searchType, @criteriaList_[0],
criteriaCount, AWD_USE_SQL, nil);
where criteriaList is defined as
criteriaList_: array of TSearch_Criteria;
After all that is said and done we can now look at the C# code, which I cannot get to work. I'm sure I'm doing something wrong here, or my C header is not translated correctly. My project does compile correctly, but when the function is called, I get a "FALSE" value back, which indicates that the function did not execute correctly in the DLL.
My C# code thus far:
/*** 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; } }
}
My C# call to the C# function looks like this
var callResult = UnsafeAwdApi.CallAwdApiLookup(IntPtr.Zero, 0, true, 'W',
ref searchCriteria[0], criteriaCount,
66, null);
where searchCriteria and criteriaCount is defined as
List<SearchCriteria> criteriaList = new List<SearchCriteria>();
var searchCriteria = criteriaList.ToArray();
var criteriaCount = (ushort)searchCriteria.Length;
and adding 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);
}
Like I said, my code compiles correctly, but when the function executes, it returns "FALSE", which should not be the case as the Delphi function does return data with the exact same input.
I know I'm definitely doing something wrong here, and I've tried a couple of things, but nothing seems to be working.
Any assistance or nudge in the right direction would be greatly appreciated.
Thanks, Riaan