델파이 7에서 SOAP 방식으로 닷넷서비스와 통신을 하는 프로그램을 만들었는데요.
비스타에서 에러가 나길래 뜯어보니.. SOAP 함수 호출시 Access violation 이 납니다.
비스타에서만 뭔가가 안될 경우엔 우선적으로 DEP 쪽을 확인해보는데.. 역시나 DEP 문제더군요.
DEP 가 비스타만의 문제는 아니지만 비스타에서는 기본적으로 모든 프로그램에 DEP 가 활성화되어있다보니 하드웨어가 DEP를 지원만 한다면 프로그램이 제대로 실행안되는 경우가 발생합니다. 외부 컴포넌트를 쓸 경우에도 그렇고..
결론적으로 델파이 7에 기본적으로 있는 Rio.pas 가 원인이었고.. 구글을 통해 해결책을 찾았습니다.
두군데를 고쳐주면 되구요. 적용해보니.. 문제없이 잘 돌아갑니다.
function TRIO.GenVTable(const IID: TGUID): Boolean; 에서
{ Allocate two blocks – one for the vtable itself, one for }
{ the thunks. }
GetMem(IntfTable, (Length(IntfMD.MDA) + NumEntriesInIInterface) * 4);
IntfTableP := @IntfTable;
GetMem(IntfStubs, (Length( IntfMD.MDA) + NumEntriesInIInterface) * StubSize );
// DEP 관련해서 문제가 있어서 여기서부터 추가
{ TODO -owilli -cpatch : windows xp NX patch }
{$IFDEF MSWINDOWS}
IntfStubs := Virtualalloc (Nil,(Length( IntfMD.MDA) + NumEntriesInIInterface) * StubSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
{$ENDIF}
{$IFDEF LINUX}
GetMem(IntfStubs, (Length( IntfMD.MDA) + NumEntriesInIInterface) * StubSize);
{$ENDIF}
// 여기까지
{ Load the IUnknown vtable entries }
VTable := PPointer(IntfTable);
Crack.QIFn := _QIFromIntf;
destructor TRIO.Destroy; 에서
if IntfTable <> nil then
FreeMem(IntfTable);
// DEP 관련해서 문제가 있어서 여기서부터 추가
{ TODO -owilli -cpatch : windows xp NX patch }
if IntfStubs <> nil then
// FreeMem(IntfStubs);
{$IFDEF MSWINDOWS}
Virtualfree (IntfStubs,0,MEM_RELEASE);
{$ENDIF}
{$IFDEF LINUX}
FreeMem(IntfStubs);
{$ENDIF}
// 여기까지
if FContext <> nil then
FContext.Free;