Delphi高阶问题 (300分)

  • 主题发起人 坏蟑螂
  • 开始时间

坏蟑螂

Unregistered / Unconfirmed
GUEST, unregistred user!
最近得到一个DLL,应该是用C写的,无源码。其中有个函数使用了类似
int sprintf(char* szString, char* szFormat, ...);
的形式,需要用Delphi去调用。

我相信用VC先做一个DLL,给这个函数做个“外壳”函数如下:
int myfunc(char* buff)
{
... //从buff中将各参数分离为p1、p2、p3、p4....
sprintf(str, format, p1, p2, p3, p4, ...);
}
再用Delphi去调用这个“外壳”函数,应该可以。
但对此产生兴趣,希望听听高人高见。

不论是用array of const也好,分析VC的va_list的结构也好,
还是用嵌入汇编直接操纵堆栈等等等等,希望各位各抒高见,
让我能够学到Delphi真正高级的“Power”。。。。

另外,说什么“高阶问题”,纯属为了吸引眼球。其实我等
初学咋练,如何提得出什么真正高阶的问题。还望各位高人
原谅,不吝赐教。谢谢。
 
你试试用数组。

procedure myfun(a:array of PChar);
 
很简单呀,用一个WSDL Generator将其导出为wdsl文件,就可以看到该Dll的函数声明,
然后就在delphi中按照wdsl文件的格式写沙,
extrafunction 函数名称
external 外部文件 name '文件名称';
 
请问WSDL Generator哪里有?
 
char* 就等于pchar了,没必要a:array of PChar
 
结构最清晰的代码:
定义一个结构:
SPRec=Record
SNum: Word ;//参数个数
P : packed array [1..51] of array [0..181] of char
//51个够了吧!!!
End;

procedure 调用;
var _sp:SPRec;
begin
_sp.snum:=5;
move(string('参数1'#0)[1],_sp.p[1],length('参数1'#0'));
move(string('参数2'#0)[1],_sp.p[2],length('参数2'#0'));
move(string('参数3'#0)[1],_sp.p[3],length('参数3'#0'));
move(string('参数4'#0)[1],_sp.p[4],length('参数4'#0'));
move(string('参数5'#0)[1],_sp.p[5],length('参数5'#0'));
myfunc(@_sp);
end;

struct SPRec {
unsigned int SNum;//参数个数
char *P[50][181]
//51个够了吧!!!
};
myfunc(struct SPRec *mybuff);stdcall;
{
... //从mybuff中将各参数分离为p1、p2、p3、p4....
sprintf(str, format, p1, p2, p3, p4, ...);
}
 
分离各个参数,参见我的帖子:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1289838
 
可变参数的函数(引用wenyue的回答)

来自:wenyue, 时间:2001-11-23 16:49:00, ID:746810
用下面的方法可以实现任意个数参数的函数
你看GETPARAM和TEST函数的写法
TEST是一个可以处理任意多个参数的函数,他访问其指定参数使用GETPARAM(N)来获得
而PROC1,PROC2....是为了编译器通过而定义的函数类型(你可以定义100个,反正定义是不
占据代码空间的)
DELPHI没有直接编写象WRITE,WRITELN的MAGIC函数的方法
WRITE,WRITELN等都是编译器直接对其进行了处理
但是使用如TEST的方法却基本上可以达到和WRITE相同的效果(我用GETPARAM来处理堆栈里的
参数)
另外,正规的写法推荐使用ARRAY OF CONST,当然那不是一种严格意义的多参数的写法
但TEST是

type proc1=procedure (count,p1:integer)
cdecl;
type proc2=procedure (count,p1,p2:integer)
cdecl;
type proc3=procedure (count,p1,p2,p3:integer)
cdecl;
type proc4=procedure (count,p1,p2,p3,p4:integer)
cdecl;
type proc5=procedure (count,p1,p2,p3,p4,p5:integer)
cdecl;
//....................
function getparam(n:integer):integer
register;
asm
shl eax,2
mov eax,[ebp+8+eax]
end;

procedure test(count:integer)
cdecl;
Var i:integer;
begin
for i:=1 to count do
ShowMessage(IntToStr(getparam(i)));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
proc4(@test)(4,1,2,3,4);
proc5(@test)(5,1,2,3,4,5);
end;


 
没看懂,眼花,休息一下再来看
 
直接用cdecl方式引入就可以了嘛!至于参数,
char* 是指向c风格的字符串的指针嘛。
 
顶部