So... I am sorry if I have posted the question at the wrong place, yet I couldnt find a better place.
Anyway, my problem is as follows:
A week ago, we had to bring back to life some old projects of the firm. The projects are ... not too complex yet very big, and the real problem is that they are written in DELPHI 6 ... . The proccess of rewriting them on C# is soon to begin but we face the pending problem: The projects have to be operational, even only for inner firm operators. SO, an idea was born - to write wcf services for the database related operations of the delphi projects and then create the C# projects over that. So far so good, but here comes the bummer. We can't seem to find a way to consume the WCF from a delphi 6 project.
As my analisys goes so far, from articles in the internet, this is possible. However, I am not entirely sure that is possible on Delphi 6 (usually it is about higher versions of Delphi - 7, CodeGear and so on). As it is said, the best way to verify is to attempt, so ... we tried to connect an empty delphi project to a WCF Service.
About the service:
The service is a simple WCF Service that we actually use in a different project written on Silverlight, and the Silverlight project has no problems consuming the service.
What happens with Delphi:
Following tutorial procedure, we create a new delphi project -> new Project -> other. From the nodes we click 'Web Services' -> web services Importer... . Than in the new window we enter the adress of the service: -> button Generate and voala - a Unit file with the Services interfaces is generated.
The file looks like this:

Unit Unit2;

interface

uses Types, XSBuiltIns;
type

  IService1 = interface(IInvokable)
    ['{0C53375F-5890-4A30-AD9D-A53304764616}']
    procedure SelectAllImotsByEKATTE(var parameters: SelectAllImotsByEKATTE);  stdcall;
    procedure SelectAllCompOBRbyEKATTE(var parameters: SelectAllCompOBRbyEKATTE);  stdcall;
    procedure SelectAllCompPolzByEKATTE(var parameters: SelectAllCompPolzByEKATTE);  stdcall;
    procedure SelectMinMaxIdOfImotiByEkatte(var parameters: SelectMinMaxIdOfImotiByEkatte);  stdcall;
    procedure comboekatte(var parameters: comboekatte);  stdcall;
    procedure selectAllMestnosti_visual(var parameters: selectAllMestnosti_visual);  stdcall;
    procedure FilMas(var parameters: FilMas);  stdcall;
    procedure SelectMinMaxIdOfImotiByEkatteOchertania(var parameters: SelectMinMaxIdOfImotiByEkatteOchertania);  stdcall;
    procedure selectAllImotsByEkatte_visual(var parameters: selectAllImotsByEkatte_visual);  stdcall;
    procedure selectAllTrainoPolzvane_visual(var parameters: selectAllTrainoPolzvane_visual);  stdcall;
    procedure AllEkatteTa(var parameters: AllEkatteTa);  stdcall;
    procedure AllOblasti(var parameters: AllOblasti);  stdcall;
    procedure NasMqsto(var parameters: NasMqsto);  stdcall;
    procedure Obshtini_vOblast(var parameters: Obshtini_vOblast);  stdcall;
    procedure GradoveSela(var parameters: GradoveSela);  stdcall;
    procedure ekkate_otNasMqsto(var parameters: ekkate_otNasMqsto);  stdcall;
    procedure ValidateLogin(var parameters: ValidateLogin);  stdcall;
    procedure IntersectPoly(var parameters: IntersectPoly);  stdcall;
    procedure SaveIntersections(var parameters: SaveIntersections);  stdcall;
    procedure ProveriBlokaZaPreiz4islqvane(var parameters: ProveriBlokaZaPreiz4islqvane);  stdcall;
    procedure InsertShapesGeometryInDBase(var parameters: InsertShapesGeometryInDBase);  stdcall;
    procedure MergePolygons(var parameters: MergePolygons);  stdcall;
    procedure SaveGeometry(var parameters: SaveGeometry);  stdcall;
    procedure SelectGeometry(var parameters: SelectGeometry);  stdcall;
    procedure SelectGeometryXP(var parameters: SelectGeometryXP);  stdcall;
    procedure SelectGeometryXPofZemlishte(var parameters: SelectGeometryXPofZemlishte);  stdcall;
    procedure UpdateGeometry(var parameters: UpdateGeometry);  stdcall;
    procedure FillGrid(var parameters: FillGrid);  stdcall;
    procedure SelectPointByEkatte(var parameters: SelectPointByEkatte);  stdcall;
    procedure SelectCompByUserId(var parameters: SelectCompByUserId);  stdcall;
    procedure SelectUserIdByUserName(var parameters: SelectUserIdByUserName);  stdcall;
    procedure SelectOblasti(var parameters: SelectOblasti);  stdcall;
    procedure SelectObshtini(var parameters: SelectObshtini);  stdcall;
    procedure SelectZemlByObstID(var parameters: SelectZemlByObstID);  stdcall;
    procedure RegisterCompanyOfUser(var parameters: RegisterCompanyOfUser);  stdcall;
    procedure DeletePolygonByCompAndPole(var parameters: DeletePolygonByCompAndPole);  stdcall;
    procedure SelectIdOfSelectedPolygon(var parameters: SelectIdOfSelectedPolygon);  stdcall;
    procedure EditPole(var parameters: EditPole);  stdcall;
    procedure InsertPole(var parameters: InsertPole);  stdcall;
    procedure FillCultureGrid(var parameters: FillCultureGrid);  stdcall;
    procedure EditCulture(var parameters: EditCulture);  stdcall;
    procedure InsertCulture(var parameters: InsertCulture);  stdcall;
    procedure InsertUpdatePolygonFromShape(var parameters: InsertUpdatePolygonFromShape);  stdcall;
    procedure FillCultureQueryGrid(var parameters: FillCultureQueryGrid);  stdcall;
    procedure FillCultureQueryPoleCombo(var parameters: FillCultureQueryPoleCombo);  stdcall;
    procedure FillCultureQueryCultureCombo(var parameters: FillCultureQueryCultureCombo);  stdcall;
    procedure InsertUpdateCultureQuery(var parameters: InsertUpdateCultureQuery);  stdcall;
    procedure SendMailAboutRegisteredUser(var parameters: SendMailAboutRegisteredUser);  stdcall;
    procedure FillAdministratorGrid(var parameters: FillAdministratorGrid);  stdcall;
    procedure InsertUpdatePolygonFromDigitizer(var parameters: InsertUpdatePolygonFromDigitizer);  stdcall;
  end;


implementation

uses InvokeRegistry;

initialization
  InvRegistry.RegisterInterface(TypeInfo(IService1), '', 'utf-8');

end.

As promising as that looks it doesnt work. When build the compilator returns error - Undeclared identifier FOR ABSOLUTELY every single one of the procedures.
We tried so many things that I cant even remember now, yet we cant get rid of this error (we can change it with a different one but stil ... ).
As I have absolutely no knowledge of Delphi, Pascal or whatever, I dont know if this is something, but I notice that the procedure parameters are not a list of the real parameters of the service method, yet just the name of the procedure itself. Ex - 'procedure SelectAllImotsByEKATTE(var parameters: SelectAllImotsByEKATTE); stdcall;' - is 'public List<string> SelectAllImotsByEKATTE (int number, string byName);' in the service.

Ok, I think I covered as much as I could, if there is anything else that needs to be explained just say so.
I will truly appriciate if someone can help find the answers to these questions:
Is Delphi 6 at particular able to consume WCF Services.
If it does, what are we doing wrong
Any ideas if we can get rid of the Undeclared Identifier...
Is it possible that the problem is in the configuration of the WCF Service.

Any and all help will be really appriciated. Sorry for the long post.

Dani AI

Generated

Short answer: Delphi 6 can talk to WCF services, but only when the service exposes a “plain SOAP” contract that Delphi’s old SOAP runtime understands. WCF defaults (wsHttpBinding, DataContractSerializer, multiple WSDL/import files and WS-* features) frequently produce WSDLs that Delphi’s importer cannot fully handle. For interoperability you want a basicHttpBinding endpoint and an ASMX-like WSDL (XmlSerializer/document‑literal wrapped) on the service side. (learn.microsoft.com)

Why you see “Undeclared identifier”: Delphi’s importer often either (a) doesn’t follow WSDL/wsdl:import and xsd:import chains, or (b) suppresses generation of some schema types. The importer will put a comment like “The following types … are not being represented” when that happens. WCF often emits several separate WSDL/XSD files; Delphi wants a single usable WSDL. The usual fix is to flatten the WSDL (or request a single WSDL from the service) before importing. (stackoverflow.com)

Practical steps to try (in order)

  • Add or expose a basicHttpBinding endpoint on the WCF service, enable metadata, and (if possible) use XmlSerializerFormat on the contract/operations so the WSDL looks ASMX-like. Then fetch a single WSDL (use ?singleWsdl or your server-side behavior to emit a flattened WSDL). Test the saved WSDL in a browser first. (learn.microsoft.com)
  • Import the saved single WSDL file with Delphi’s Import WSDL wizard (or run WSDLIMP.EXE). In the wizard/flags, make sure you allow generation of wrapper types (unwind literal params) and do not suppress “unused” types — those options control whether the importer emits the wrapper classes you need. Inspect the generated .pas carefully for “types not represented” messages. (docwiki.embarcadero.com)
  • If types are still missing or names collide, either (a) manually edit the generated unit (small fixes are common), (b) create a tiny .NET façade that exposes a simple ASMX/basicHttp endpoint Delphi can consume, or (c) build the SOAP envelope by hand from Delphi (THTTPRIO/Indy) as a last resort.

Example (call pattern, adapt to the exact names in your generated unit):

var
  RIO: THTTPRIO;
  Svc: IService1;
  Params: TSelectAllImotsByEKATTE; // use the exact generated type name
begin
  RIO := THTTPRIO.Create(nil);
  try
    RIO.WSDLLocation := 'C:\path\to\flattened.wsdl';
    RIO.Service := '<service name from WSDL>';
    RIO.Port := '<port name from WSDL>';
    RIO.QueryInterface(IService1, Svc);
    Params := TSelectAllImotsByEKATTE.Create; // if generated type is a class
    try
      // set fields on Params according to the generated type
      Svc.SelectAllImotsByEKATTE(Params);
      // read result fields from Params (names are in the generated unit)
    finally
      Params.Free;
    end;
  finally
    RIO.Free;
  end;
end;

If none of the above works quickly, the lowest-effort, most reliable options are to expose a basicHttpBinding/XmlSerializer endpoint, or build a tiny .NET wrapper (COM or simple HTTP façade) that Delphi 6 can call. As noted, later Delphi versions also struggled with WCF WSDLs — the importer is fragile; flattening WSDLs or adapting the service is usually the path that actually gets you running. (stackoverflow.com)

We have had similar issues even with XE2 and have finally abandoned it. Somehow what's generated is not usable enough, or a lot of definitions are missing. We've been unable to find any reasonable solution around this problem. Even changing the output by hand was not enough to get things going (and you do not want to start building and posting XML). If you do find something, please share.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.