es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

La función P/Invoked de C# desde BPL devuelve el mismo puntero al registro de Delphi independientemente de la entrada.

Estoy intentando utilizar una función del paquete BPL extranjero para el cual no tengo acceso al código.

Mientras tengo éxito en Delphi, en C# sigo obteniendo el mismo valor, independientemente de la entrada.

Uso externo de BPL en Delphi

type
PRecord = ^TRecord;
TRecord = packed record
S: string;
LW: LongWord;
end;

function GetValue(W : Word) : PRecord; external ‘package.bpl’ name ‘@Unit@Function$qqrus’;

Llamando a GetValue() con diferentes entradas se obtienen registros diferentes, lo cual es correcto.

Uso externo de BPL en C#

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TRecord
{
public string S;
public int LW;
}

[DllImport(“package.bpl”, EntryPoint = “@Unit@Function$qqrus”, CharSet = CharSet.Unicode)]
static extern IntPtr GetValue(ushort number);

public static TRecord GetDelphiValue(ushort number)
{
var ptr = GetValue(number);
return (TRecord) Marshal.PtrToStructure(ptr, typeof(TRecord));
}

Llamando a GetDelphiValue() con diferentes entradas siempre se obtiene el mismo puntero y, por lo tanto, la estructura.

¿Qué me he perdido?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Parece que el problema radica en el código de C# donde se devuelve el mismo puntero cada vez que se llama a GetValue(), independientemente de la entrada. Esto podría deberse a que el parámetro de entrada ushort no se está pasando correctamente a la función.

    Una sugerencia sería cambiar el tipo ushort a Word en la firma de la función y modificar el atributo extern para que use CallingConvention.StdCall. Además, asegúrese de que se esté utilizando el tipo correcto para el campo LW en la estructura TRecord (el código de Delphi utiliza LongWord, por lo que debería cambiarse a uint en C#).

    Aquí está el código C# modificado:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TRecord
    {
        public string S;
        public uint LW;
    }
    
    [DllImport("package.bpl", EntryPoint = "@Unit@Function$qqrus", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    static extern IntPtr GetValue(Word number);
    
    public static TRecord GetDelphiValue(Word number)
    {
        var ptr = GetValue(number);
        return (TRecord)Marshal.PtrToStructure(ptr, typeof(TRecord));
    }
    

    Con estos cambios, la función GetDelphiValue() debería devolver registros diferentes dependiendo de la entrada proporcionada, al igual que en el código de Delphi.

Comments are closed.