Search code examples
c#cstructmarshallingdllimport

C# - Call C++ DLL function whit ref


I am trying to call a DLL function in C++ from my C# code.

DLL function code and struct (C++):

typedef struct{
    Operacion RespuestaOperacion; 
    char var1[256];           
    int var2;                      
    char var3[33];                    
    char var4[1025];                 
    char var5[20];                       
    char var6[11];                  
    char var7[7];                      
} TResultado;

typedef void (WINAPI *TPROC_PAY_VENTA)(long Importe, bool ProcessMessages, TResultado *Resultado);

My C# code:

[StructLayout(LayoutKind.Sequential)]
public struct TResultado
{
    public Operacion RespuestaOperacion;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string var1;
    public int var2;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
    public string var3;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1025)]
    public string var4;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string var5;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
    public string var6;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 7)]
    public string var7;   
}

[DllImport("DLLName.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Pay_Venta(long importe, bool ProcessMessages, ref TResultado Resultado);

TResultado Resultado = new TResultado();
long cent = 1;

CRPayIUN_Venta(cent, true, ref Resultado);

ERROR!!!

The problem I am having is that when passing through the function it tells me:

Additional information: Attempt to read or write in the protected memory. This often indicates that there is other memory corrupted.

What am I doing wrong?? Thanks for your time.


Solution

  • CallingConvention = CallingConvention.Cdecl is a problem. The C function typedef is:

    typedef void (WINAPI *TPROC_PAY_VENTA)(long Importe, bool ProcessMessages, TResultado *Resultado);

    WINAPI means stdcall. Change the calling convention on the DllImport line to CallingConvention.Stdcall.

    It definitely makes sense that a memory violation error occurs here; if the C# code thinks the calling convention is cdecl it will add a few bytes to the stack pointer, which unbalances the stack.