Invoking an unmanaged char function returns char *

I have a function in unmanaged C / C ++ code (dll) that returns a structure containing a char array. I created a C # struct to get this return value up by calling a function. And up the call to this function, I get "System.Runtime.InteropServices.MarshalDirectiveException"

This is the C declaration:

typedef struct T_SAMPLE_STRUCT {
int num;
char text[20];
} SAMPLE_STRUCT;

SAMPLE_STRUCT sampleFunction( SAMPLE_STRUCT ss );

This is a C # declaration:

struct SAMPLE_STRUCT
{
    public int num;
    public string text;
}

class Dllwrapper
{
    [DllImport("samplecdll.dll")]
    public static extern SAMPLE_STRUCT sampleFunction(SAMPLE_STRUCT ss);

}

I am using 1 byte ASCII.

Does anyone have a clue or decision on how to do this?

+3
source share
6 answers

C MarshalAs (UnmanagedType.ByValTStr). CLR . .

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
public struct T_SAMPLE_STRUCT {

    /// int
    public int num;

    /// char[20]
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=20)]
    public string text;
}

public partial class NativeMethods {

    /// Return Type: SAMPLE_STRUCT->T_SAMPLE_STRUCT
    ///ss: SAMPLE_STRUCT->T_SAMPLE_STRUCT
    [System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="sampleFunction")]
public static extern  T_SAMPLE_STRUCT sampleFunction(T_SAMPLE_STRUCT ss) ;

}

​​ PInovke Interop Assistant (), CodePlex. PInvoke # VB.Net.

+5

P/Invoke : , char * char [] ( char * , ).

, , :

public fixed char text[20];

, unsafe , .

+2

C:

#pragma pack(push, 1)
typedef struct T_SAMPLE_STRUCT {
  int num;
  char text[20];
};
#pragma pack(pop)

#:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct T_SAMPLE_STRUCT
{
  [MarshalAs(UnmanagedType.I4)]
  public int num;

  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
  public string text;
}
+2

, :

void receiveStruct( SAMPLE_STRUCT ss )
void returnStruct(SAMPLE_STRUCT &ss)

, JaredPar:

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct T_SAMPLE_STRUCT
{
    /// int
    public int num;

    /// char[20]
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string text;
}

.

!

0

, , , . , , . ++/CLI, StructLayoutAttribute . , blittable . , :

[StructLayout(LayoutKind.Sequential, Size=24)]
public struct T_SAMPLE_STRUCT
{    
    public int num;
    // to get the string here, you'd need to get a pointer
    public char firstChar;     
}

// or

[StructLayout(LayoutKind.Sequential)]
public struct T_SAMPLE_STRUCT
{    
    public int num;
    public byte c0;
    public byte c1;
    public byte c2;
    public byte c3;
    public byte c4;
    public byte c5;
    public byte c6;
    public byte c7;
    public byte c8;
    public byte c9;
    public byte c10;
    public byte c11;
    public byte c12;
    public byte c13;
    public byte c14;
    public byte c15;
    public byte c16;
    public byte c17;
    public byte c18;
    public byte c19;
}

, ( ), blittable, , ,

0
source

First you need to put StructLayout [Sequential] in your structure, and I think it will work

[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
struct SAMPLE_STRUCT
{    
    public int num;
    [ MarshalAs( UnmanagedType.ByValArray, SizeConst=20 )] 
    public char[] text;
} 
-1
source

Source: https://habr.com/ru/post/1707186/


All Articles