盛大面试的一道题目。竟然过一天后,在做引擎绑定Cal3d的时候,看Cal3d的PAS代码,发现类竟然没有方法和对象,刚开始以为作者保密呢?现在看来是自己的无知,以前根本就不注意 几个参数指令的作用,只知道STDCALL,现在看来太无知了。。。要是早一天研究估计我都OK了。。。。其实理解很好理解。。。
哎~~~~~~总算长见识了,以后做DELPHI和C++兼容的东西不会那么难受了。不过话说回来,这东西看了一次也就补上了。呵呵,没啥大不了的。。。

在delphi的动态连接库中,如此做
uses Classes;

type
TStringListIntf = class
public
function Add(const S: pchar): Integer; virtual; cdecl; abstract;
procedure Clear; virtual; cdecl; abstract;
procedure Delete(Index: Integer); virtual; cdecl; abstract;
procedure Exchange(Index1, Index2: Integer); virtual; cdecl; abstract;
function IndexOf(const S: pchar): Integer; virtual; cdecl; abstract;
procedure Insert(Index: Integer; const S: pchar); virtual; cdecl; abstract;
function Strings(Index: Integer): pchar; virtual; cdecl; abstract;
procedure Sort; virtual; cdecl; abstract;
procedure SaveToFile(const filename: pchar); virtual; cdecl; abstract;
procedure LoadFromFile(const filename: pchar); virtual; cdecl; abstract;
function GetText: pchar; virtual; cdecl; abstract;
procedure SetText(const text: pchar); virtual; cdecl; abstract;
end;

TMyStringList = class(TStringListIntf)
private
SL: TStringList;
public
constructor Create;
destructor Destroy; override;
function Add(const S: pchar): Integer; override;
procedure Clear; override;
procedure Delete(Index: Integer); override;
procedure Exchange(Index1, Index2: Integer); override;
function IndexOf(const S: pchar): Integer; override;
procedure Insert(Index: Integer; const S: pchar); override;
function Strings(Index: Integer): pchar; override;
procedure Sort; override;

procedure SaveToFile(const filename: pchar); override;
procedure LoadFromFile(const filename: pchar); override;
function GetText: pchar; override;
procedure SetText(const text: pchar); override;
end;

function CreateStringList(): TStringListIntf; stdcall; export;
procedure FreeStringList(SL: TStringListIntf); stdcall; export;

implementation

function CreateStringList(): TStringListIntf;
begin
result := TMyStringList.Create;
end;

procedure FreeStringList(SL: TStringListIntf);
begin
SL.Free;
end;

{ TMyStringList }

function TMyStringList.Add(const S: pchar): Integer;
begin
result := SL.Add(S);
end;

procedure TMyStringList.Clear;
begin
inherited;
SL.Clear;
end;

constructor TMyStringList.Create;
begin
SL := TStringList.Create;
end;

procedure TMyStringList.Delete(Index: Integer);
begin
inherited;
SL.Delete(Index);
end;

destructor TMyStringList.Destroy;
begin
SL.Free;
inherited;
end;

procedure TMyStringList.Exchange(Index1, Index2: Integer);
begin
inherited;
SL.Exchange(Index1, Index2);
end;

function TMyStringList.GetText: pchar;
begin
result := pchar(SL.Text);
end;

function TMyStringList.IndexOf(const S: pchar): Integer;
begin
result := SL.IndexOf(S);
end;

procedure TMyStringList.Insert(Index: Integer; const S: pchar);
begin
inherited;
SL.Insert(Index, S);
end;

procedure TMyStringList.LoadFromFile(const filename: pchar);
begin
inherited;
SL.LoadFromFile(filename);
end;

procedure TMyStringList.SaveToFile(const filename: pchar);
begin
inherited;
SL.SaveToFile(filename);
end;

procedure TMyStringList.SetText(const text: pchar);
begin
inherited;
SL.Text := text;
end;

procedure TMyStringList.Sort;
begin
inherited;
SL.Sort;
end;

function TMyStringList.Strings(Index: Integer): pchar;
begin
result := pchar(SL.Strings[Index]);
end;

end.

把CreateStringList, FreeStringList在工程文件中引出,编译出dll文件
wisenow 发表于 2005-1-17 9:32:27
在VC中的声明
定义接口
typedef class TStringListIntf
{
public:
virtual int _cdecl Add(const char *S) { return 0; };
virtual void _cdecl Clear(void) { return ;};
virtual void _cdecl Delete(int Index) { return ;};
virtual void _cdecl Exchange(int Index1, int Index2) { return ;};
virtual int _cdecl IndexOf(const char *S) { return 0;};
virtual void _cdecl Insert(int Index, const char *S) { return;};
virtual char* _cdecl Strings(int Index) { return "";};
virtual void _cdecl Sort(void) { return ;};

virtual void _cdecl SaveToFile(const char *filename) { return; };
virtual void _cdecl LoadFromFile(const char *filename) { return;};

virtual char* _cdecl GetText() { return "";};
virtual void _cdecl SetText(const char *text) { return;};

} *PStringListIntf;

typedef PStringListIntf(_stdcall *CreateStringList)(void);
typedef void(_stdcall *FreeStringList)(PStringListIntf SL);

定义全局变量(相对来说的,可以放到使用StringList的类或函数中)
TStringListIntf *m_StringList;
HINSTANCE m_DllHandle;

// 加载动态连接库
m_DllHandle = LoadLibrary("D:\\vcdelphi\\dll\\Project2.dll");
// 文件是例子,你指定为你的dll文件即可
if (m_DllHandle)
{
CreateStringList _stdcall proc;
proc = (CreateStringList)GetProcAddress(m_DllHandle, "CreateStringList");
m_StringList = proc(); //创建StringList对象
}

// 使用StringList
m_StringList->Add("abc");
m_StringList->SaveToFile("d:\\rere.txt");

// 在不是用StringList要调用dll中的FreeStringList释放内存,这个不用说了吧
上面的代码测试通过,其他的功能还没有是过,不过我写上的应该不会有什么问题
如果你还要用到StringList的其他功能,你就照猫画虎吧