none
Interop Question: C DLL to C# RRS feed

  • Question

  • Hello, 

    I'm a beginner with interop services and having some difficulty getting it working. 

    I'm hoping someone can take a look at what I've done and critique it.

    Basically pass in a card number in the request and get information back from the response.

    When I pass in the card number the log file tells me that I did not pass in a card number even though it is in the object. 

    It must be how I am passing in the cardRequest object that is not correct but I'm not entirely sure how to proceed.

    Thanks. 

    C syntax:

    int Card_Transactions(int transType, pCardRequest cardRequest, pCardResponse cardResponse, int (*Com)(char *));

    C Structure - Request:

    typedef struct _CardRequest { char CardNumber[80]; long Balance; }
    CardRequest, *pCardRequest

    C structure - response:

    typedef struct _CardResponse
    {
    char Result;
    char Display[41];
    char Date[11];
    char Time[9];
    char RespCode[4];
    char CardNum[20];
    char ExpDate[5];
    long InitialBalance;
    long RemainingBalance;
    } CardResponse, *pCardResponse

    This is what I've done:

    [StructLayout(LayoutKind.Sequential)] public struct _CardRequest { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string CardNumber;

    public uint Balance; }

    [StructLayout(LayoutKind.Sequential)]

    public struct _CardResponse { public byte Result; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)] public string Display; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)] public string Date; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)] public string Time; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)] public string RespCode; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string CardNum; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)] public string ExpDate; public uint InitialBalance; public uint RemainingBalance; }

    Then I set it up as:

    [DllImport("cdcauth.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
    public static extern int CardTransactions(int transactionType, ref CardRequest cardRequest, ref CardResponse cardResponse, IntPtr com);

    So in my method it looks like:

    CardRequest cardRequest = new CardRequest();
    CardResponse cardResponse = new CardResponse();
    
    cardRequest.CardNumber = "546732723487600543872";
    
    int success = CardTransactions(7, ref cardRequest, ref cardResponse, IntPtr.Zero);

    Sucess will be 0 which means fail. 

    The log file the DLL generates says that a card number was not passed.

    So i'm not sure if I set up the CardRequest object correctly or not. 

    Thanks for taking a look.




    • Edited by GreenWasabi Monday, September 23, 2013 1:23 PM
    Monday, September 23, 2013 1:23 PM

Answers

  • Try encoding like the line below.  A string and a char in Net library are two bytes so you really need one byte

    byte[] number = Encoding.UTF8.GetBytes("546732723487600543872");


    jdweng

    • Marked as answer by GreenWasabi Monday, September 23, 2013 4:04 PM
    Monday, September 23, 2013 2:58 PM

All replies

  • the variable types int and long may be different number of bytes so you may need to try different types lline int32 or int 64.  I did find one error in you calling function shown below.  Since the C++ doesn't use pointers for these parameters you should be not using "ref" in the C# code.

    from :  ref CardRequest cardRequest, ref CardResponse cardResponse

    to :  CardRequest cardRequest, CardResponse cardResponse


    jdweng


    Monday, September 23, 2013 1:54 PM
  • Hi Joel, 

    I previously did a few method calls with "ref" in c# and I could pass in values and it returned with other values populated.  If I take out the "ref" it will give me back an error. 

    When the "ref" in it the response object will give me the date and time of method execution.  So it does tell me that it is getting to the DLL but it's just not passing the card number correctly.

    The only difference with this one is the TypeDef structure that I've never encountered before.

     Thanks for the advice.

    Monday, September 23, 2013 2:50 PM
  • Try encoding like the line below.  A string and a char in Net library are two bytes so you really need one byte

    byte[] number = Encoding.UTF8.GetBytes("546732723487600543872");


    jdweng

    • Marked as answer by GreenWasabi Monday, September 23, 2013 4:04 PM
    Monday, September 23, 2013 2:58 PM
  • A lot of C++ application also requires a '\0' at the end of the character array.

    jdweng

    Monday, September 23, 2013 3:04 PM
  • Hi Joel, 

    This worked. 

    Thanks for the assistance!

    Monday, September 23, 2013 4:04 PM