Trouble with struct and delphi dll
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5

Thread: Trouble with struct and delphi dll

  1. #1
    Join Date
    Oct 2007
    Posts
    25

    Unhappy Trouble with struct and delphi dll

    I'm coding a csharp program which needs to read values from a dll coded in delphi. I've got it working for the most part but am still having an issue with certain values.

    The example code given to me for using the dll in delphi (there's no example code for csharp) is as follows:

    Code:
    type
      TStockRec = packed record
        ItemNo: String[15];
        Description: String[40];
        ItemType: Char;
        InStock: String[210];         //21 x 10
        SalesOrders: String[210];     //21 x 10
        PurchaseOrders: String[210];  //21 x 10
        UnitCost: String[18];
        LastPurchasePrice: String[18];
        SellingPrice: String[108];    //6 x 18
        ItemTaxCode: String[4];
        ItemTax: String[18];
        MinimumMargin: String[18];
        VariableDescription: Char;
      end;
    The String[x] variables I can receive no problem, but the Char ones with my current code give me blank values and with some of the fiddling I've tried changing data types I land up with errors.

    Here is the code I'm currently using:

    Code:
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=1)]
    		
       		public struct TStockRec
    		{
    			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
    			public string ItemNo;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)]
    		    public string Description;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)]
    		    public string ItemType;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 211)]
    		    public string InStock;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 211)]
    		    public string SalesOrders;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 211)]
    		    public string PurchaseOrders;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
    		    public string UnitCost;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
    		    public string LastPurchasePrice;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 109)]
    		    public string SellingPrice;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
    		    public string ItemTaxCode;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
    		    public string ItemTax;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
    		    public string MinimumMargin;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)]
    		    public string VariableDescription;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)]
    		    public string Active;
    		}
    
                    [DllImport("Cust.dll")]
    		public static extern bool GetStockFirst(ref TStockRec StockRec,ref bool eof);
    Inside my function:

    Code:
    bool success;
    TStockRec myData = new TStockRec();
    success = GetStockFirst(ref myData,ref eof);
    Can anyone suggest how I can get the Char fields (ItemType and Active) to pass the data I need?

  2. #2
    Join Date
    Oct 2007
    Posts
    25

    Re: Trouble with struct and delphi dll

    Got an update, nearly got the problem sorted, but still having an issue.

    Seems that the "char" variables needed a size constraint of 2 not 1, however I get the following weird issue:

    It cuts off a character to do this.

    Here's an example, focusing on the last 3 variables in the struct:

    Correct Data (i.e. as it should be):
    Minimum Margin (ends in): 0.00
    VariableDescription: Y
    Active: N

    What I'm getting with SizeConst=18 for minimumargin:
    Minimum Margin (ends in): 0.0
    VariableDescription: Y
    Active: (blank)

    If I have SizeConst = 19 for minimum margin then that variable is correct but "variabledescription" is blank.

    Same goes for VariableDescription vs Active. I can't seem to get both working together. If I set VariableDescription to a SizeConst=3 or higher then I get a "YN" which is the 2 values.

    I'm considering just accepting it as a single variable and I'll split it in code, but it doesn't seem like the right thing to do.

  3. #3
    Join Date
    May 2007
    Posts
    1,546

    Re: Trouble with struct and delphi dll

    I don't mean to alarm you but this:

    Code:
    	InStock: String[210];         //21 x 10
    maps as
    Code:
    	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 210)]
    	public string InStock;
    You're off by 1 everywhere
    www.monotorrent.com For all your .NET bittorrent needs

    NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.

  4. #4
    Join Date
    Oct 2007
    Posts
    25

    Re: Trouble with struct and delphi dll

    hehe, yeah thanks. I was aware of that, forgot to mention it.

    When set to the same numbers as the delphi code it doesn't work, according to a website (can't find it atm) the delphi variables are "null terminated" or something like that and results in the csharp needed the sizes to be 1 value extra in size - also the reason for the SizeConst=2 working for the Char variables.

    I think I may have solved my problem though (just busy doing more tests atm) by using a csharp Char instead of String for these values. Will post my results soon.

  5. #5
    Join Date
    Oct 2007
    Posts
    25

    Re: Trouble with struct and delphi dll

    Ok, well after pulling my hair out for long enough, I've got enough of a working piece of code to do what I need. It's not great but it works for my purposes and perhaps will help someone in the future.

    Final Code:
    Code:
    public struct TStockRec
    		{
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
    		    public string ItemNo;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)]
    		    public string Description;
    		    [MarshalAs(UnmanagedType.U1)]
    		    public char ItemType;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 211)]
    		    public string InStock;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 211)]
    		    public string SalesOrders;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 211)]
    		    public string PurchaseOrders;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
    		    public string UnitCost;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
    		    public string LastPurchasePrice;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 109)]
    		    public string SellingPrice;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
    		    public string ItemTaxCode;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
    		    public string ItemTax;
    		    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
    		    public string MinimumMargin;
    		    [MarshalAs(UnmanagedType.U1)]
    		    public char VariableDescription;
    		    [MarshalAs(UnmanagedType.U1)]
    		    public char Active;
    		}
    
                    [DllImport("Cust.dll")]
    		public static extern bool GetStockFirst(ref TStockRec StockRec,ref bool eof);
    Notes/Problems encountered:
    SizeConst needs to be +1 for all fields for some reason.
    Each return string contains an invalid character in the first char of the string, the first variable contains 2 of these (hence the +2 on size for ItemNo).
    Char variables work as a U1 unmanaged type.
    When switching from Strings to Char variables it cuts off the last char on the string. I've been unable to avoid this but it does not affect me for what I'm doing so I havn't tried to fix it.

    For those wondering, I'm only using a few of the variables, using this dll to pull them from a software package and then put them into a database. As long as the variables I need are accurate the rest don't matter to me, hence the lack of effort to get this working perfectly.

    Unfortunately there's not much information on dealing with struct passing to/from dlls done in delphi, so I've had to do most of this from trial and error.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center