===VC++에서 선언 ============
#define MAX_ROUTE 5
struct _time {
char date[8];
char time[6];
};
typedef struct _time stTime;
struct _address {
char type; // 1=IP address, 2=host Name, 3 = E-Mail
// 4=Group Name
char name[20];
};
typedef struct _address Address;
struct _stRouteInfo {
Address srcAddr;
unsigned int srcPort;
Address tgtAddr;
unsigned int tgtPort;
stTime conTime;
};
typedef struct _stRouteInfo stRouteInfo;
struct _stAlert {
unsigned int alertID;
char user[20];
stTime ctime;
char loginUser[20];
char sensor[10];
char analyzer[10];
// Address attacker;
// unsigned int attackPort;
// Address target;
// unsigned int targetPort;
char attackName[20];
char attackType[20];
unsigned int confidence;
// char falsePosi;
char attackMessage[80];
char attackImpact[50];
unsigned int autoResponse;
// unsigned int decision;
// stTime ddate;
unsigned int rnum;
stRouteInfo rinfos[MAX_ROUTE];
};
typedef struct _stAlert stAlert;
BOOL CM_getAlert(stAlert* alert);
======Delphi 에서=========
//Record 선언
type
PPChar = ^PChar;
sttime = Record
Date : PPChar;
Time : PPChar;
end;
Address = Record
ttype : PPChar;
name : PPChar;
end;
stRouteInfo = Record
srcAddr : Address;
srcPort : Longword;
tgtAddr : Address;
tgtPort : Longword;
conTime : stTime;
end;
ptAlert = ^tAlert;
tAlert = Record
AlertID : Longword;
User : PPChar;
ctime : sttime;
LoginUser : PPChar;
Senser : PPChar;
Analyzer : PPChar;
AttackName : PPChar;
AtackType : PPChar;
Confidence : Longword;
AttackMessage : PPChar;
AttackImpact : PPChar;
AutoResponse : Longword;
Rnum : Longword;
rinfos : array[1..5] of stRouteInfo;
end;
Function CM_getAlert(alert:ptAlert):Boolean;FAR; CDECL;
implementation
Function CM_getAlert(alert :ptAlert)
:Boolean;external 'comm.dll' name 'CM_getAlert';
procedure TForm1.BitBtn4Click(Sender: TObject);
var
pRecord : ptAlert;
i : integer;
bb : boolean;
begin
new(pRecord);
CM_getAlert(pRecord);
edit2.Text := inttostr (pRecord.AlertID);
edit3.Text := pRecord^.User; <==error : incomplitible
types : 'String'and'PPChar'
edit4.Text := pRecord^.ctime.date;
edit5.Text := pRecord^.cTime.time;
edit6.Text := pRecord^.LoginUser;
.
.
.
.
.
.
dispose(pRecord);
end;
왜 이런에라가 나죠?
C 언어에서의 char date[8];는 델파이에서는 PChar입니다. 님이 만들어낸 소스에는 ^PChar로 정의되어 있는데 그렇게 사용하면 에러납니다. PChar에 P가 붙어 있듯이 이 자체가 Char의 Point입니다. ^Pchar는 C로 치면 Char**입니다. 그리고 참고로 char date[8]은 본질적으로 char*입니다.
그리고 아래는 더 큰 문제가 있는데 String과 PChar를 혼동하고 있다는 것입니다.
아시는 사람은 아시다시피 델파이의 하위 버젼에서는 PChar라는 것이 없었습니다. 파스칼 언어의 표준은 String을 사용하지요. 그런데 다른 언어와 Interfacing할려면 특히 C와 할려면 C에서 사용하는 스트링을 지원해야겠죠. C는 Null terminating 구조를 사용합니다. 이는 쉽게 말해서 문자열은 맨앞 위치의 포인터만 가지고 있고 NULL이 되는 시점까지 문자열로 간주하겠다는 것입니다. 좀 단순 무식하죠. 파스칼의 String은 맨앞위치에 그 문자열의 길이가 얼마나 되는지를 알려주는 정보를 가지고 있습니다. 파스칼이 좀 진보된 형태죠.
그리고 둘은 별개의 것으로 함수들도 제각각 따로 만들어져 있습니다.
String용으로 옛날부터 사용하던 Length나 Copy등등을 이용할수 있습니다.
PChar용은 비교적 근래의 것으로서 대체로 함수명에 PChar용임을 암시하는 표시가 있습니다. 그리고 둘의 관계를 치환해주는 함수들도 많이 있습니다. PChar 도움말을 참조 바랍니다.
그리고 아래 소스를 보면
> edit3.Text := pRecord^.User; <==error : incomplitible
> types : 'String'and'PPChar'
라고 되어 있는데 당연한 에러 메시지입니다.
edit3.Text는 PChar 타입이 아니라 String타입니다. pRecord^.User는 PChar 타입이니 PChar 형식의 스트링을 String으로 치환해주는 PCharToStr(함수 이름이 정확치는 않음, 도움말 참조 바람)같은 함수를 사용하여 변환을 해준뒤 사용해야합니다.
참고로 String을 PChar로 바꾸는건 변수앞에 @를 사용하면 됩니다.
그리고 큰 문제가 하나 더 있는데,
C에서 정의한
> struct _stAlert {
> unsigned int alertID;
> char user[20];
> stTime ctime;
> char loginUser[20];
...
를 델파이에서 아래와 같이 선언 하였는데
> tAlert = Record
> AlertID : Longword;
> User : PPChar;
> ctime : sttime;
> LoginUser : PPChar;
...
이렇게 하면 절대 제대로 될리 없죠. 프로그램이 안죽는게 다행일 정도입니다.
> User : PPChar;
는 4바이트 Char point의 point일뿐입니다.
C 에서 선언한 것처럼 20바이트 문자열이 되겠끔 해야합니다.
array[0..19] of char로 선언(Index가 0부터 시작함에 주의)하면 되겠습니다. 그리고 이는 엄밀히 말해서 PChar가 아니라 String입니다.
tAlert = Record
AlertID : Longword;
User : array[0..19] of char;
ctime : sttime;
LoginUser : array[0..19] of char;
...
처럼 선언하고 사용할때도 String 사용하듯이 하면 되겠습니다.
저는 직접 만들어서 해보지는 않았으므로 100% 보장은 못합니다.
혹 다른 문제가 있으면 다시 질문하세요.
김문진 wrote:
> ===VC++에서 선언 ============
> #define MAX_ROUTE 5
>
> struct _time {
> char date[8];
> char time[6];
> };
> typedef struct _time stTime;
>
> struct _address {
> char type; // 1=IP address, 2=host Name, 3 = E-Mail
> // 4=Group Name
> char name[20];
> };
> typedef struct _address Address;
>
> struct _stRouteInfo {
> Address srcAddr;
> unsigned int srcPort;
> Address tgtAddr;
> unsigned int tgtPort;
> stTime conTime;
> };
> typedef struct _stRouteInfo stRouteInfo;
>
> struct _stAlert {
> unsigned int alertID;
> char user[20];
> stTime ctime;
> char loginUser[20];
> char sensor[10];
> char analyzer[10];
> // Address attacker;
> // unsigned int attackPort;
> // Address target;
> // unsigned int targetPort;
> char attackName[20];
> char attackType[20];
> unsigned int confidence;
> // char falsePosi;
> char attackMessage[80];
> char attackImpact[50];
> unsigned int autoResponse;
> // unsigned int decision;
> // stTime ddate;
> unsigned int rnum;
> stRouteInfo rinfos[MAX_ROUTE];
> };
> typedef struct _stAlert stAlert;
>
> BOOL CM_getAlert(stAlert* alert);
>
>
>
> ======Delphi 에서=========
> //Record 선언
> type
> PPChar = ^PChar;
>
> sttime = Record
> Date : PPChar;
> Time : PPChar;
> end;
>
> Address = Record
> ttype : PPChar;
> name : PPChar;
> end;
>
> stRouteInfo = Record
> srcAddr : Address;
> srcPort : Longword;
> tgtAddr : Address;
> tgtPort : Longword;
> conTime : stTime;
> end;
>
> ptAlert = ^tAlert;
>
> tAlert = Record
> AlertID : Longword;
> User : PPChar;
> ctime : sttime;
> LoginUser : PPChar;
> Senser : PPChar;
> Analyzer : PPChar;
> AttackName : PPChar;
> AtackType : PPChar;
> Confidence : Longword;
> AttackMessage : PPChar;
> AttackImpact : PPChar;
> AutoResponse : Longword;
> Rnum : Longword;
> rinfos : array[1..5] of stRouteInfo;
> end;
>
>
> Function CM_getAlert(alert:ptAlert):Boolean;FAR; CDECL;
>
> implementation
>
> Function CM_getAlert(alert :ptAlert)
> :Boolean;external 'comm.dll' name 'CM_getAlert';
>
> procedure TForm1.BitBtn4Click(Sender: TObject);
> var
> pRecord : ptAlert;
> i : integer;
> bb : boolean;
> begin
> new(pRecord);
> CM_getAlert(pRecord);
>
> edit2.Text := inttostr (pRecord.AlertID);
> edit3.Text := pRecord^.User; <==error : incomplitible
> types : 'String'and'PPChar'
> edit4.Text := pRecord^.ctime.date;
> edit5.Text := pRecord^.cTime.time;
> edit6.Text := pRecord^.LoginUser;
> .
> .
> .
> .
> .
> .
> dispose(pRecord);
> end;
>
> 왜 이런에라가 나죠?
>