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; override;
 
    class 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> inherited;
 
public:
	__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> inherited;
 
public:
	/* {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> inherited;
 
public:
	/* {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>.

时间: 2024-08-07 08:38:54

c++builder 泛型的相关文章

如何把匿名类型.GetType()返回的对象传进泛型里面[转]

//怎么取得匿名类型的Type放到 //泛型T当中?? var 匿名 = new { A = 0, B = 1 }; Type t = 匿名.GetType(); //然后下面 var xx = dbContext.Database.SqlQuery<t>("sql"); //就悲剧了 var xx2 = dbContext.Database.SqlQuery<dynamic>("sql"); //xx2有列表,但是都是Object..~~~

C#基础之泛型

1.泛型的本质 泛型的好处不用多说,在.NET中我看到有很多技术都是以泛型为基础的,不过因为不懂泛型而只能对那些技术一脸茫然.泛型主要用于集合类,最主要的原因是它不需要装箱拆箱且类型安全,比如很常用的List<T>.对于List<T>我以后还想进行深究,现在我写了一个超简版的MyList<T>集合,如下面第一段代码所示.代码很简单,但在写的过程中有一个细节,如果我为listInt赋值string类型的变量时编译器会提示报错.编译器很智能,但是从这个现象中你会不会好奇泛型

Scala入门到精通——第十六节 泛型与注解

本节主要内容 泛型(Generic Type)简介 注解(Annotation)简介 注解常用场景 1. 泛型(Generic Type)简介 泛型用于指定方法或类可以接受任意类型参数,参数在实际使用时才被确定,泛型可以有效地增强程序的适用性,使用泛型可以使得类或方法具有更强的通用性.泛型的典型应用场景是集合及集中中的方法参数,可以说同java一样,scala中泛型无处不在,具体可以查看scala的api //单个泛型参数的使用情况 class Person[T](var name:T) cla

泛型趣谈

原文出处: 四火的唠叨 ava中的泛型带来了什么好处?规约.就像接口定义一样,可以帮助对于泛型类型和对象的使用上,保证类型的正确性.如果没有泛型的约束,程序员大概需要在代码里面使用大量的类型强制转换语句,而且需要非常清楚没有标注的对象实际类型,这是容易出错的.恼人的.但是话说回来,泛型可不只有规约,还有很多有趣的用法,容我一一道来. 泛型擦除 Java的泛型在编译阶段实际上就已经被擦除了(这也是它和C#泛型最本质的区别),也就是说,对于使用泛型的定义,对于编译执行的过程,并没有任何的帮助(有谁能

asp.net泛型结合反射的简单Base封装

泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确定一个或多个具体参数,其的具体参数可延迟到客户代码中声明.实现.这意味着使用泛型的类型参数T,写一个类MyList<T>,客户代码可以这样调用:MyList<int>, MyList<string>或 MyList<MyClass>.这避免了运行时类型转换或装箱操作的代价和风

从fastjson多层泛型嵌套解析,看jdk泛型推断

给你一组json数据结构,你把它解析出来到项目中,你会怎么做? // data1 sample { "code" : "1", "msg" : "Success", "data" : { "userid1" : { "name" : "Zhangsan", "sex" : "male" } } } // da

.NET编程01(泛型)

一:Object 类型:一切类型的父类,通过继承,子类拥有父类一切属性和行为:任何父类出现的地方,都可以用子类来代替: 用一个方法来完成多个方法做的事 /// <summary>    /// 普通方法类    /// </summary>    public class CommonMethod    {        /// <summary>        /// 打印个int值        /// </summary>        /// <

c#系统泛型委托

Action<T> 无返回值的系统泛型委托 namespace ConsoleApp1 { public class UserInfo { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } class Program { private static List<UserInfo> getInit() { return new List<User

泛型2

万用字符(wildcard) 以动物Animal类为例,怎样才能创建出一种ArrayList<?>里面既可以保存ArrayList<Dog>,又可以保存ArrayList<Cat>? public void takeAnimals(ArrayList<? extends Animal> animals){  //泛型中extends同时代表继承和实现. for(Animal a : animals){ a.eat(); } } 我们可以这样调用该函数: Ar