Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

185
Views
Which way of marshaling is correct for this C code?

I have two different implementation of marshaling C code into C#.

First of all the C code is:

int GetVersion(char * pVer, size_t * piSize);

My first attempt in C#(I don't show the DllImport part):

static extern int GetVersion( byte[] ver, ref UIntPtr size );

And the other attempt in C#:

static extern int GetVersion([MarshalAs(UnmanagedType.LPStr)] StringBuilder ver, ref ulong size);

I came through these from different examples in net. But I cannot conclude which one is correct.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Bare bones: we can always do this

static extern int GetVersion(IntPtr ver, ref UIntPtr size );

I would never write this because I don't like what this generates for A->W conversion:

static extern int GetVersion([MarshalAs(UnmanagedType.LPStr)] StringBuilder ver, ref UIntPtr size);

Also, if this is a true counted string, the P/Invoke code doesn't work as it wants a 0 after the end.

I would normally write

static extern int GetVersion( byte[] ver, ref UIntPtr size );

in which you must first create ver at the maximum size. You can then convert ver to string using the stuff in System.Text.Encoding. GetVersion() almost certainly passes a constant back, so you can hardcode the correct encoding (probably ASCII anyway).

There's a pretty good chance you're missing [DllImport(..., CallingConvention=CallingConvention.Cdecl)] causing you some memory corruption, but I can't actually tell.

Mistake: don't use ulong for size_t. size_t is UIntPtr on all supported platforms.


Comment suggests a completely different signature GetDevInfo(int Index, DevInfo * pdevInfo); This is a different thing altogether and there's clearly one best choice:

const int IDLength = 100;
[StructLayout(LayoutKind.Sequential)]
struct DeviceInfo {
   [MarshalAs(UnmanagedType.ByValArray, SizeConst = IDLength)]
   byte[] ID;
}

static extern /* I don't know what's here because missing from comment */
    GetDevInfo(int index, ref strcut DeviceInfo info);

string GetInfo(int index)
{
    var info = new DeviceInfo();
    info.ID = new byte[IDLength];
    GetDevInfo(info.ID);
    return System.Text.Encoding.ASCII.GetString(info.ID, 0, strlen(info.ID));
}

int strlen(byte[] bytes)
{
    int i;
    for (i = 0; i < bytes.Length && bytes[i] != 0; i++)
        ;
    return i;
}
````
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!