首页 > 代码库 > c++builder 泛型

c++builder 泛型

http://docwiki.embarcadero.com/RADStudio/XE6/en/How_to_Handle_Delphi_Generics_in_C%2B%2B

这个泛型是为delphi编写的,c++builder不能直接使用,非要用的话按下面的例子,先建立个delphiunit,集成新类,然后再c++builder引用此单元头文件,就可以了。真麻烦。

How to Handle Delphi Generics in C++

Go Up to Handling Delphi Features in C++Builder Index

 

This topic describes some programming issues that you might encounter when dealing with generics, a feature supported by Delphi.

Delphi generics are exposed to C++ as templates. However, it is important to realize that the instantiations occur on the Delphi side, not in C++. Therefore, you can only use these template for types that were explicitly instantiated in Delphi code. For example, let‘s declare a simple generic, TList<T>, in Delphi:

 unit DelphiUnit; interface  uses System.Generics.Collections; type  MyTList<T> = class(TList<T>)  public    // Anchors constructor/destructor    constructor Create;    destructor Destroy; overrideclass procedure Cleanup(var L: MyTList<T>); static;  end// DoubleList: instantiates MyTList<double>  DoubleList = class(MyTList<double>)  end// StringList: instantiates MyTList<string>  StringList = class(MyTList<string>)  end; implementation class procedure MyTList<T>.Cleanup(var L: MyTList<T>);begin  L.Free;end; constructor MyTList<T>.Create;begin  inherited;end; destructor MyTList<T>.Destroy;begin  inherited;end; end.

The interface above is exposed to C++ as the following:

 // CodeGear C++Builder// Copyright (c) 1995, 2012 by Embarcadero Technologies, Inc.// All rights reserved // (DO NOT EDIT: machine generated header) ‘DelphiUnit.pas‘ rev: 24.00 (Windows) #ifndef DelphiunitHPP#define DelphiunitHPP #pragma delphiheader begin#pragma option push#pragma option -w       // Display all warnings#pragma option -w-inl   // Functions %s are not expanded inline#pragma option -w-8111  // Accessing deprecated entity#pragma option -Vx      // Zero-length empty class member#pragma pack(push,8)#include <System.hpp>	// Pascal unit#include <SysInit.hpp>	// Pascal unit#include <System.Generics.Collections.hpp>	// Pascal unit#include <System.Generics.Defaults.hpp>	// Pascal unit#include <System.Types.hpp>	// Pascal unit //-- user supplied ----------------------------------------------------------- namespace Delphiunit{//-- type declarations -------------------------------------------------------template<typename T> class DELPHICLASS MyTList__1;// Template declaration generated by Delphi parameterized types is// used only for accessing Delphi variables and fields.// Don‘t instantiate with new type parameters in user code.template<typename T> class PASCALIMPLEMENTATION MyTList__1 : public System::Generics::Collections::TList__1<T>{	typedef System::Generics::Collections::TList__1<T> inheritedpublic:	__fastcall MyTList__1(void);	__fastcall virtual ~MyTList__1(void);	static void __fastcall Cleanup(MyTList__1<T>* &L);};  class DELPHICLASS DoubleList;class PASCALIMPLEMENTATION DoubleList : public MyTList__1<double>{	typedef MyTList__1<double> inheritedpublic:	/* {DelphiUnit}MyTList<System_Double>.Create */ inline __fastcall DoubleList(void) : MyTList__1<double>() { }	/* {DelphiUnit}MyTList<System_Double>.Destroy */ inline __fastcall virtual ~DoubleList(void) { };  class DELPHICLASS StringList;class PASCALIMPLEMENTATION StringList : public MyTList__1<System::UnicodeString>{	typedef MyTList__1<System::UnicodeString> inheritedpublic:	/* {DelphiUnit}MyTList<System_string>.Create */ inline __fastcall StringList(void) : MyTList__1<System::UnicodeString>() { }	/* {DelphiUnit}MyTList<System_string>.Destroy */ inline __fastcall virtual ~StringList(void) { };  //-- var, const, procedure ---------------------------------------------------}	/* namespace Delphiunit */#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_DELPHIUNIT)using namespace Delphiunit;#endif#pragma pack(pop)#pragma option pop #pragma delphiheader end.//-- end unit ----------------------------------------------------------------#endif	// DelphiunitHPP

C++ code linking with the .obj created from the above Delphi unit can use instances of MyTList__1<double> or MyTList__1<System::String>.

 void UseDLists(){  // C++ code can use the Generics defined in Delphi directly  // as long as the C++ code limits itself to types for which  // the generic was instantiated on the Delphi side. For example,  // since the Delphi Unit instantiates MyTList<String>  // and MyTList<double> we can use these here.  // However, if we try to use MyTList__1<char> we‘ll get  // errors since the Delphi side did not instantiate  // MyTList<AnsiChar>.  MyTList__1<double>* dblList = new MyTList__1<double>();  dblList->Add(1.0);  dblList->Add(1.5);  double d = dblList->Items[1];#ifdef _WIN64  delete dblList#else  MyTList__1<double>::Cleanup(dblList);#endif   MyTList__1<System::String> *strList = new MyTList__1<System::String>();  strList->Add("First");  strList->Add("Second");  strList->Add("Third");  assert(strList->Count == 3);   System::String str = strList->Items[0];  assert(str == "First");  assert(strList->Items[1] == "Second");  assert(strList->Items[2] == "Third");   strList->Insert(0, "Inserted");  assert(strList->Count == 4);  assert(strList->Items[0] == "Inserted");  assert(strList->Items[1] == "First");   strList->Reverse();  assert(strList->Items[0] == "Third");  assert(strList->Items[1] == "Second");  assert(strList->Items[2] == "First");  assert(strList->Items[3] == "Inserted");   assert(strList->Contains("Inserted"));  assert(!strList->Contains("Not Inserted"));   strList->Sort();  strList->Remove("Inserted");   assert(strList->Items[0] == "First");  assert(strList->Items[1] == "Second");  assert(strList->Items[2] == "Third"); #ifdef _WIN64  delete strList;#else  MyTList__1<System::String>::Cleanup(strList);#endif}

If C++ code attempts to use a Delphi generic for types that were not instantiated in Delphi, you‘ll get errors at link time. For example, the following code attempts to use MyTList__1<char> when the Delphi code did not explicitly instantiate MyTList<AnsiChar>:

 void UseListOfChar(){  MyTList__1<char>* charList = new MyTList__1<char>();  charList->Add(‘a‘);  // ...}

While the code above compiles, the following errors are generated at link time:

 [ilink32 Error] Error: Unresolved external ‘Delphiunit::MyTList__1<char>::‘ referenced from CPPUNIT.OBJ[ilink32 Error] Error: Unresolved external ‘__fastcall Delphiunit::MyTList__1<char>::MyTList__1<char>()‘ referenced from CPPUNIT.OBJ[ilink32 Error] Error: Unresolved external ‘__fastcall System::Generics::Collections::TList__1<char>::Add(const const char)‘ referenced from CPPUNIT.OBJ[ilink32 Error] Error: Unable to perform link

To eliminate the error, you have to make sure that the Delphi code uses the type MyTList<AnsiChar>.

c++builder 泛型