Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6796639
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T18:30:44+00:00 2026-05-26T18:30:44+00:00

I have a Delphi DLL that contains the following types: type TStepModeType = (smSingle,

  • 0

I have a Delphi DLL that contains the following types:

type
  TStepModeType = (smSingle, smMultiStep);

  TParameter = record
    Number: Integer;
  end;

  TStruct = record
    ModType: PAnsiChar;
    ModTypeRev: Integer;
    ModTypeID: Integer;
    RecipeName: PAnsiChar;
    RecipeID: Double;
    RootParamCount: Integer;
    StepMode: TStepModeType;
    ParamCount: Integer;
    Parameters: array of TParameter;
  end;

I need to call this DLL from C# passing a ref object corresponding to the Delphi types that the DLL will fill and return. I have defined structures in my C# code like this:

enum stepModeType
{
    Single,
    MultiStep
}

[StructLayout(LayoutKind.Sequential)]
struct parameter
{
    public int Number;
}

[StructLayout(LayoutKind.Sequential)]
struct recipe
{
    public string modType;
    public int modTypeRev;
    public int modTypeId;
    public string recipeName;
    public double recipeId;
    public int rootParamCount;
    public stepModeType stepMode;
    public int paramCount;
    public IntPtr parameters;
}

I was doing fine until I ran into the dynamic array (Parameters: array of TParameter) in the Delphi code. I understand that dynamic arrays are a Delphi only construct, so I chose to use an IntPtr in my C# code in the hopes of just getting a pointer to the array and pulling the contents. Unfortunately, I am rather new to this interop stuff and I am not sure how to deal with the IntPtr.

Let’s say the Delphi DLL populates the dynamic array with 2 parameter items. Can someone possibly show me the C# code that would get those 2 parameter items out of the array once it gets passed back from the Delphi DLL to my C# calling application?

UPDATE: Well, as it happens the Delphi code I was given was a simplified version. One of our Delphi developers thought it would be easier to get started with the simplified version than the real version, which is substantially more complex containing dynamic arrays of dynamic arrays of dynamic arrays. Anyway, I am now completely over my head. I only know enough about Delphi to be dangerous. Below is the code for the real structures in the Delphi code. Any further guidance on how to deal with these structures from my C# calling application would be greatly appreciated. It may not even be possible with the nesting of dynamic arrays such that they are.

type
  TStepModeType = (smSingle, smMultiStep);

  TParamValue = record
    strVal: String;
    fVal: Double;
    Changed: Boolean;
  end;

  TSteps = array of TParamValue;

  TRule = record
    Value: String;
    TargetEnabled: Boolean;
  end;

  TParamInfo = record
    Caption: String;
    Units: String;
    RuleCount: Integer;
    Rules: array of TRule;
  end;

  TParameter = record
    Info: TParamInfo;
    Steps: TSteps;
  end;

  TStruct = record
    ModType: PAnsiChar;
    ModTypeRev: Integer;
    ModTypeID: Integer;
    RecipeName: PAnsiChar;
    RecipeID: Double;
    RootParamCount: Integer;
    StepMode: TStepModeType;
    ParamCount: Integer;
    Parameters: array of TParameter;
  end;
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T18:30:45+00:00Added an answer on May 26, 2026 at 6:30 pm

    I am assuming trust that the DLL has a function that deallocates the recipe struct. That’s something that you can’t possibly hope to do from C#. More on this point later on.

    A Delphi dynamic array is not a valid interop type. It really should only used internally to Delphi code compiled with a single version of the compiler. Exposing it publically is akin to exporting C++ classes from a DLL.

    In an ideal world you would re-work the Delphi code so that it exported the array using a proper interop type. However, in this case it is actually relatively easy for you to do the marshalling without adjusting the Delphi code.

    Delphi dynamic arrays were introduced way back in Delphi 4 and their implementation has remained unchanged since then. The array of T dynamic array variable is effectively a pointer to the first element. The elements are laid out sequentially in memory. The dynamic array variable also maintains (at negative offsets) a reference count and the size of the array. You can safely ignore these since you are neither modifying the dynamic array nor needing to ascertain its size.

    Using IntPtr for the Parameters field is perfect. Because TParameter contains just a single 32 bit integer you can use Marshal.Copy to copy it straight to an int[] array.

    So, when the Delphi DLL returns, you can do the final marshalling step using Marshal.Copy.

    if (theRecipe.paramCount>0)
    {
        int[] parameters = new int[theRecipe.paramCount];
        Marshal.Copy(theRecipe.parameters, parameters, 0, theRecipe.paramCount);
        ... do something with parameters
    }
    

    That deals with the dynamic array, but as it happens you have another problem with your code as it stands. You are declaring the two strings as string in the C# struct. This means that the marshaller will take responsibility for freeing the memory returned by the Delphi DLL in the two PAnsiChar fields. It will do so by calling CoTaskMemFree. I’m fairly sure that’s not going to match the allocation of the PAnsiChar fields made in the Delphi code.

    As stated above, I would expect that the contract for this interface is that you call a further DLL function to deallocate the heap memory referenced by the recipe struct. That is, the two strings, and the dynamic array.

    To deal with this issue from C# you need to make sure that the marshaller does not attempt to deallocate the PAnsiChar fields. You can achieve that by declaring them as IntPtr in the C# struct. Then call Marshal.PtrToStringAnsi to convert to a C# string.


    I’ve had to make a few assumptions about the contract between the Delphi code and the C# code in order to write the above. If any of my assumptions are incorrect please update the question and I’ll try to make this answer match! I hope this helps.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a Delphi 7 dll that exports the following function: function StringTest(var StringOut
I'm creating a DLL in Delphi that must have the following C++ structure. DWORD
I have a legacy delphi dll. I created a class library that imports the
In Delphi I have a structure like this: TCustomerInfo = Packed Record CustomerNo: Integer;
I have a C++ Builder DLL that must link against a Delphi package (BPL),
I have a Delphi DLL that houses a form which uses a variety of
I have a Delphi DLL that I did not write, but need to call
We have a COM dll written in delphi in our bin folder that call
I have a Delphi 6 application that sends bitmaps to a DirectShow DLL in
I have a Delphi application similar to Taskbar Shuffle that includes a hook dll.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.