batbertram
asked on
How to marshal array of custom data type using P/Invoke in C++ .Net
Experts,
I am currently trying to call functions from an unmanaged c++ dll using P/Invoke in C++ .Net (2008). I am completely new to P/Invoke, but have managed to stumble through by using various online references until now.
One particular function of the unmanaged dll is defined as follows:
PUNCH_BUREAU_RESULT_CODE PunchBureauDoAuthorisation (
char *pszPrimaryIPAddress,
unsigned short usiPrimaryIPPort,
char *pszSecondaryIPAddress,
unsigned short usiSecondaryIPPort,
unsigned short usiResponseTimeoutInMs,
char rgcTransactionTimestamp[12 ],
char *pszPAN,
char rgcExpiryDate[4],
char *pszStationID,
__int64 i64Amount,
unsigned short usiBatch,
unsigned short usiCurrencyCode,
unsigned short usiNumberOfProducts,
PRODUCT_DATA_DSCR rgProductData[18],
char rgcActionCode[3],
char rgcApprovalCode[6]);
PRODUCT_DATA_DSCR is a struct defined in the library.
I currently have the following for the P/Invoke:
[DllImport("PunchBureauInt erfaceDLL8 0.dll",
EntryPoint="?PunchBureauDo Authorisat ion@@YA?AW 4PUNCH_BUR EAU_RESULT _CODE@@PAD G0GGQAD010 _JGGGQAUPR ODUCT_DATA _DSCR@@11@ Z",
CallingConvention=CallingC onvention: :StdCall)]
static PUNCH_BUREAU_RESULT_CODE PunchBureauDoAuthorisation (
String^ pszPrimaryIPAddress,
System::UInt16 usiPrimaryIPPort,
String^ pszSecondaryIPAddress,
System::UInt16 usiSecondaryIPPort,
System::UInt16 usiResponseTimeoutInMs,
String^ rgcTransactionTimestamp,
String^ pszPAN,
String^ rgcExpiryDate,
String^ pszStationID,
System::Int64 i64Amount,
System::UInt16 usiBatch,
System::UInt16 usiCurrencyCode,
System::UInt16 usiNumberOfProducts,
???PRODUCT_DATA_DSCR rgProductData[18]???,
String^ rgcActionCode,
String^ rgcApprovalCode);
The questionsI have currently are:
- What is the syntax for marshalling the arguments of the function? I presume I have to marshall the char arrays to Strings, but if I try the follwing syntax:
...
[MarshalAs(UnmanagedType:: ByValTStr, SizeConst = 12)]
String^ rgcTransactionTimestamp,
...
I get the compiliation error 'API call 'DefineCustomeAttribute" failed.
- How can I successfully marshal an array of a custom datatype?
I think I have been thrown in the deep end of P/Invoke! Many thanks for your help in advance.
Alvin
I am currently trying to call functions from an unmanaged c++ dll using P/Invoke in C++ .Net (2008). I am completely new to P/Invoke, but have managed to stumble through by using various online references until now.
One particular function of the unmanaged dll is defined as follows:
PUNCH_BUREAU_RESULT_CODE PunchBureauDoAuthorisation
char *pszPrimaryIPAddress,
unsigned short usiPrimaryIPPort,
char *pszSecondaryIPAddress,
unsigned short usiSecondaryIPPort,
unsigned short usiResponseTimeoutInMs,
char rgcTransactionTimestamp[12
char *pszPAN,
char rgcExpiryDate[4],
char *pszStationID,
__int64 i64Amount,
unsigned short usiBatch,
unsigned short usiCurrencyCode,
unsigned short usiNumberOfProducts,
PRODUCT_DATA_DSCR rgProductData[18],
char rgcActionCode[3],
char rgcApprovalCode[6]);
PRODUCT_DATA_DSCR is a struct defined in the library.
I currently have the following for the P/Invoke:
[DllImport("PunchBureauInt
EntryPoint="?PunchBureauDo
CallingConvention=CallingC
static PUNCH_BUREAU_RESULT_CODE PunchBureauDoAuthorisation
String^ pszPrimaryIPAddress,
System::UInt16 usiPrimaryIPPort,
String^ pszSecondaryIPAddress,
System::UInt16 usiSecondaryIPPort,
System::UInt16 usiResponseTimeoutInMs,
String^ rgcTransactionTimestamp,
String^ pszPAN,
String^ rgcExpiryDate,
String^ pszStationID,
System::Int64 i64Amount,
System::UInt16 usiBatch,
System::UInt16 usiCurrencyCode,
System::UInt16 usiNumberOfProducts,
???PRODUCT_DATA_DSCR rgProductData[18]???,
String^ rgcActionCode,
String^ rgcApprovalCode);
The questionsI have currently are:
- What is the syntax for marshalling the arguments of the function? I presume I have to marshall the char arrays to Strings, but if I try the follwing syntax:
...
[MarshalAs(UnmanagedType::
String^ rgcTransactionTimestamp,
...
I get the compiliation error 'API call 'DefineCustomeAttribute" failed.
- How can I successfully marshal an array of a custom datatype?
I think I have been thrown in the deep end of P/Invoke! Many thanks for your help in advance.
Alvin
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
http://www.codeproject.com/KB/cs/marshalarrayofstrings.aspx
For my own experience, don't use attribute to do this work, you will be crazy and end up with no good solution with this. Using the IntPtr to handle all the pointers and you can parse any data yourself.