Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Funcion en DLL pasar de C++ a Delphi (https://www.clubdelphi.com/foros/showthread.php?t=95631)

cesarsoftware 28-03-2022 17:22:57

Funcion en DLL pasar de C++ a Delphi
 
Hola compañeros.
Estoy tratando de trasladar un codigo escrito en C++ que llama a funciones de una DLL a Delphi. El procedimiento basico esta hecho pero no comprendo o no se bien como pasar los parametros,
Escribo el codigo C++
Código:

struct MELDEVICEDATA
DWORD dwDeviceType; /* Device type (Set DEVICETYPE_TCP.) */
APIDEVICE uniDeviceInfo; /* Device information */

struct APIDEVICE
struct Tcp
char IPAddr[16]; /* IP address (e.g. “192.168.100.1”) */
long lPortNo; /* Port No. (Set 683 (fixed value).) */
char dummy[12]; /* Reserved */

DWORD WINAPI melIoctl( HWND hWnd, long lAddress, long lFunction, LPVOID lpData ); ): Longint; stdcall; /* function in DLL */

void setmachine; {
/* Set IP address */
MELDEVICEDATA MelIoctlData;
long lIPAdrLen;
char szIPAddress[] = "192.168.100.1";
DWORD dwStatus;
/* Set device type */
melIoctlData.dwDeviceType = DEVICETYPE_TCP;
/* Set IP address */
lIPAdrLen = strlen(szIPAddress);
strncpy(MelIoctlData.uniDeviceInfo.Tcp.IPAddr, szIPAddress, lIPAdrLen);
melIoctlData.uniDeviceInfo.Tcp.IPAddr[lIPAdrLen] = '\0';
/* Set port No. */
MelIoctlData.uniDeviceInfo.Tcp.lPortNo = 683;
dwStatus = melIoctl(NULL, ADR_MACHINE(1), DEV_SET_COMMADDRESS, &MelIoctlData);
}

Y ahora el codigo Delphi que casi seguro no esta bien.
Código Delphi [-]
type APIDEVICE = record
  IPAddr: ansistring;             // IP address (e.g. “192.168.100.1”)
  lPortNo: word;                  // Port No. (Set 683 (fixed value).)
  dummy: array[0..11] of UINT16;  // array of supported bus controllers
end;

type MELDEVICEDATA = packed record
  dwDeviceType: LongWord;         // Device type (Set DEVICETYPE_TCP.)
  uniDeviceInfo: APIDEVICE;       // Device information
end;

type tMELDEVICEDATA = ^MELDEVICEDATA;

function melIoctl(HWND, lAddress, lFunction: LongWord; lpData: Pointer): LongWord; cdecl; stdcall; external 'ncap.iDLL';

procedure TForm1.BotonProbarClick(Sender: TObject);
var
  MelIoctlData: tMELDEVICEDATA;
  szIPAddress: ansistring;
  dwStatus: LongWord;
begin
  StaticText1.Caption := '';
  StaticText1.Update;
  New(MelIoctlData);
  szIPAddress := AnsiString(EditCncIP.Text);
  MelIoctlData^.dwDeviceType := DEVICETYPE_TCP;
  MelIoctlData^.uniDeviceInfo.IPAddr := szIPAddress;
  MelIoctlData^.uniDeviceInfo.lPortNo := 683;
  dwStatus := melIoctl(Self.Handle, ADR_MACHINE, DEV_SET_COMMADDRESS, tMELDEVICEDATA(MelIoctlData));
//  function melIoctl(HWND: LongWord; var lAddress, lFunction: LongWord; const lpData: string): Longint; stdcall;
  StaticText1.Caption := IntToStr(dwStatus);
  if dwStatus = ME_SYSFUNC_IOCTL_ADDR then // Address error
    Beep
  else
  if dwStatus = ME_SYSFUNC_IOCTL_FUNCTION then // Function error
    Beep
  else
    Beep;
  Dispose(tMELDEVICEDATA(MelIoctlData));
end;

Si alguien es tan amable de ayudarme, lo agradecere ampliamente, cervezas incluidas

Neftali [Germán.Estévez] 29-03-2022 12:19:08

Cita:

Empezado por cesarsoftware (Mensaje 546269)
Hola compañeros.
Estoy tratando de trasladar un codigo escrito en C++ que llama a funciones de una DLL a Delphi.
...
Y ahora el codigo Delphi que casi seguro no esta bien.

Tendías que explicar qué problema hay.
¿No compila? ¿No funciona en ejecución?

Aun así hay referencias en ese código que no están disponibles por lo que también es difícil probarlo (DEVICETYPE_TCP, por ejemplo).

cesarsoftware 29-03-2022 12:32:42

Buenas Netfali.
Que majo eres, siempre dispuesto a ayudar, Gracias.
El problema es que no se si es convertido bien la funcion, sobre todo por el tema del puntero a la estructura &MelIoctlData.
No da problema de compilacion, y la funcion me devuelve un error, con lo que en teoria, al menos, la libreria funciona y no "explota"
La constante DEVICETYPE_TCP debe estar en otro fichero que por cierto no encuentro, no se si sera un tipo fijo en algun include .H de linux.
De momento le he asignado un valor para salir del paso sabiendo que me falta esa constante.
Tambien veo que ADR_MACHINE es como un array para C++ pero como no se como pasarle ese "puntero" tambien he hecho mal y como es un longorwd le he puesto a 1 hasta aprender a mandarle ese tipo de array.
Las otras constantes si estan sacadas del manual del fabricante pero DEVICETYPE_TCP no esta en el manual y es un valor OBLIGADO Y NECESARIO por ellos. Algun dia lo encontrare o les llamare a los japaneses, jejeje.
Código Delphi [-]
const
  DEVICETYPE_TCP: word = 1;
  ADR_MACHINE: LongWord = 1;
  DEV_SET_COMMADDRESS: LongWord = $FFF;             // 4095
  ME_SYSFUNC_IOCTL_FUNCTION: LongWord = $80020132;  // Function error
  ME_SYSFUNC_IOCTL_ADDR: LongWord = $80020190;      // Address error
Como veras la funcion en C++ es:
Código:

dwStatus = melIoctl(NULL, ADR_MACHINE(1), DEV_SET_COMMADDRESS, &MelIoctlData);
Mi pregunta es, ¿asi esta bien convertida a Delphi?
Código Delphi [-]
dwStatus := melIoctl(Self.Handle, ADR_MACHINE, DEV_SET_COMMADDRESS, tMELDEVICEDATA(MelIoctlData));
¿He convertido bien las estructuras?
Código:

struct MELDEVICEDATA{
DWORD dwDeviceType; // Device type (Set DEVICETYPE_TCP.)
APIDEVICE uniDeviceInfo; // Device information
}
struct APIDEVICE {
struct Tcp {
char IPAddr[16]; // IP address (e.g. “192.168.100.1”)
long lPortNo; // Port No. (Set 683 (fixed value).)
char dummy[12]; // Reserved
}
}

Código Delphi [-]
type APIDEVICE = record
  IPAddr: ansistring;             // IP address (e.g. “192.168.100.1”)
  lPortNo: word;                  // Port No. (Set 683 (fixed value).)
  dummy: array[0..11] of UINT16;  // array of supported bus controllers
end;

type MELDEVICEDATA = packed record
  dwDeviceType: LongWord;         // Device type (Set DEVICETYPE_TCP.)
  uniDeviceInfo: APIDEVICE;       // Device information
end;

type tMELDEVICEDATA = ^MELDEVICEDATA;

Espero ansiosamente tus comentos. ;?

Neftali [Germán.Estévez] 29-03-2022 18:00:14

No soy especialista en C++.
Lo mueve al foro correspondiente a ver si alguien con más conocimientos te puede ayudar.

De todas formas un primer intento del que no te puedes fiar sería:

Código Delphi [-]
type
  PTcp = ^Tcp;
  PAPIDEVICE = ^APIDEVICE;
  PMELDEVICEDATA = ^MELDEVICEDATA;

  Tcp = record
    IPAddr: array [0..15] of Char;
    lPortNo: Integer;
    dummy: array [0..11] of Char;
  end;

  APIDEVICE = record
    ValueTcp: Tcp;
  end;

  MELDEVICEDATA = record
    dwDeviceType: Integer;
    uniDeviceInfo: APIDEVICE;
  end;

cesarsoftware 29-03-2022 18:08:55

Gracias German

Espero la ayuda de los expertos.
Siento no pasar tanto por el foro como antes, tengo mucho trabajo, pero intentare pasar por aqui mas a menudo para echar una mano.


La franja horaria es GMT +2. Ahora son las 08:38:08.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi