Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

P/Invoke, c#: unsigned char losing a byte

Im working towards a dll file for a software's SDK and i'm trying to call a function to get information about the host of the software.

there are two unsigned char variables(HostMachineAddress, HostProgramVersion) in the struct the function wants and it seems like i "loose" the last byte when i try to call it from c#... if I change the SizeConst in the c# struct below to 5 i do get the missing byte, however it causes the other variable looses data.

Could someone help me find a way to solve this issue? also trying to use a class instead of struct causes system.stackoverflow error

C# Struct

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct sHostInfo
{
    public int bFoundHost;
    public int LatestConfirmationTime;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string szHostMachineName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
    public string HostMachineAddress;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string szHostProgramName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
    public string HostProgramVersion;
}

C#

[DllImport("Cortex_SDK.dll")]
public static extern int GetHostInfo(out sHostInfo pHostInfo);
like image 544
Tistatos Avatar asked Mar 07 '11 15:03

Tistatos


People also ask

What is P/Invoke?

P/In­voke is a way of call­ing C/C++ func­tions from a .NET pro­gram. It’s very easy to use. This ar­ti­cle will cover the ba­sics of using P/In­voke.

What are the two namespaces for P/Invoke?

Most of the P/Invoke API is contained in two namespaces: System and System.Runtime.InteropServices. Using these two namespaces give you the tools to describe how you want to communicate with the native component. Let's start from the most common example, and that is calling unmanaged functions in your managed code.

Do I need to know C++/CLI to use P/Invoke?

Think of P/Invoke as platform invocation, are you calling into something like the Win32 API which is very P/Invoke friendly or do you need to provide .NET bindings for an unmanaged library? Since the wrapper typically is very thin a C++/CLI wrapper doesn't necessitate that you know C++/CLI specifically.

What is PInvoke?

PInvoke.net is primarily a wiki, allowing developers to find, edit and add PInvoke * signatures, user-defined types, and any other information related to calling Win32 and other unmanaged APIs from managed code (written in languages such as C# or VB.NET).


1 Answers

Your C# struct's layout is different from the C++ one (HostProgramVersion should be last).

Also for strings marshalled as ByValTStr use [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)].

The problem with the missing last byte may be that the marshaller tries to append null to your string (as in null-terminated string). Try to use sbyte[]+ByValArray instead of a string.

like image 60
Jaroslav Jandek Avatar answered Oct 11 '22 17:10

Jaroslav Jandek