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

  • Home
  • SEARCH
  • 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 8949437
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T13:13:00+00:00 2026-06-15T13:13:00+00:00

I have a native DLL, written in Delphi, actively using callback mechanism: a callback

  • 0

I have a native DLL, written in Delphi, actively using callback mechanism: a callback function is “registered” and later called from inside of the DLL:

function RegisterCallback(CallbackProc: TCallbackProc): Integer; stdcall;

Most of the callback functions are passing plain structures by reference, like the following:

TCallbackProc = procedure(Struct: PStructType); stdcall;

where PStructType is declared as

TStructType = packed record 
  Parameter1: array[0..9] of AnsiChar;
  Parameter2: array[0..19] of AnsiChar;
  Parameter3: array[0..29] of AnsiChar;
end;
PStructType = ^TStructType;

This DLL is consumed by a .NET application, written in C#. The C# code is written very negligently and the application as a whole behaves unreliably, showing hard-to-identify exceptions, raised in different places from run to run.

I do not have reasons to suspect the DLL, because it had already proved itself as a quite robust piece of software, used in many other applications. What I am currently concerned about is the way how those structures are used in C#.

Let’s assume, that the record from above is re-declared in C# as follows:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct TStructType
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
    public string Parameter1;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string Parameter2;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)]
    public string Parameter3;
}

and the callback is declared as

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void CallbackProc(ref TStructType Struct);

Now something interesting begins. Let’s assume, that in the DLL, the registered callbacks are called in this way:

var
  Struct: TStructType;
begin
  // Struct is initialized and filled with values
  CallbackProc(@Struct);
end;

But what I see in the C# application, and what I do not like at all, that the marshaled structure is saved aside as a pointer for future use:

private void CallbackProc(ref TStructType Struct)
{
    SomeObjectList.Add(Struct); // !!! WTF?
}

As I understand, Struct variable is that created on Delphi’s stack deep inside in the DLL, and storing pointer to it on heap in client application – is a sheer adventure.

I am not a big fan/expert of C#, so please excuse my naive question, does the marshaller do something behind the scene, like copy structures onto heap or something like that, or the fact that the application sometimes works is a matter of pure chance?

Thank you in advance.

  • 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-06-15T13:13:02+00:00Added an answer on June 15, 2026 at 1:13 pm

    A C# struct is a value type. Which means that

    SomeObjectList.Add(Struct)
    

    will make a copy of the struct. So, nothing to get concerned about.

    In fact, in CallbackProc you are not operating on the object that was allocated in your Delphi code. That’s because the p/invoke marshaller had to take the raw pointer that it received and convert that into a TStructType object. And a TStructType contains C# strings which are most definitely not blittable with those Delphi character arrays. So the marshaller has already added a layer in between your C# code and the Delphi code.

    Since the function receives the structure by ref what happens is as follows:

    1. Before calling CallbackProc the marshaller de-serializes the raw unmanaged pointer to a TStructType object.
    2. CallbackProc is then passed that TStructType object by reference.
    3. When CallbackProc returns, the p/invoke marshaller serializes the TStructType object back to the original raw unmanaged pointer.

    One of the consequences of this is that changes you make to the TStructType object are not visible to the Delphi code until the callback procedure returns. Contrast that to what happens when you call a Delphi procedure passing a variable as a var parameter. In that case any changes in the procedure are visible immediately outside that procedure.

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

Sidebar

Related Questions

I have Java application which sends pointer to function (callback) to some native dll
I have a native/unmanaged DLL and it has a CreateObject function which returns a
I have written an C++/Cli wrapper for a native C++ dll, but when I
I have a function in a native DLL defined as follows: #include <string> void
I have a DLL which is written in native C++. The Visual Studio project
I have a native regular C++ Dll which I want to call from C#
I have the following function header in a native DLL: unsigned char* Version_String() I'm
I have a native Windows DLL written in C. This DLL is designed to
I have a DLL written in C# which is acessed by a native EXE
I have a C++ dll I have written (native, not .net), and I would

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.