?
Solved

How to marshal array of custom data type using P/Invoke in C++ .Net

Posted on 2010-01-11
2
Medium Priority
?
640 Views
Last Modified: 2013-12-14
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("PunchBureauInterfaceDLL80.dll",
EntryPoint="?PunchBureauDoAuthorisation@@YA?AW4PUNCH_BUREAU_RESULT_CODE@@PADG0GGQAD010_JGGGQAUPRODUCT_DATA_DSCR@@11@Z",
CallingConvention=CallingConvention::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
0
Comment
Question by:batbertram
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 
LVL 9

Expert Comment

by:magicdlf
ID: 26289629
Please read this article:
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.
0
 

Accepted Solution

by:
batbertram earned 0 total points
ID: 26420511
Thanks for the link magicdlf.  

I have tried adapting the solution but have yet to achieve the desired result.  I don't think I have the expertise required!

We are going to opt for a slight recode of the C++ libraries where it is only accepting simple datatypes, with a delimited string passed instead of the array.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It seems a simple enough task, yet I see repeated questions asking how to do it: how to pass data between two forms. In this article, I will show you the different mechanisms available for you to do just that. This article is directed towards the .N…
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
Suggested Courses

800 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question