又一个关于可变参数函数的有关问题
又一个关于可变参数函数的问题
我用VC++2005写了一个动态链接库,导出了如下函数:
现在使用Delphi调用这个导出函数,在Delphi中声明如下:
procedure SetVariables(VarList:pChar);stdcall;varargs;external 'MyDll.dll';
调用时可以这样调用:
在动态链接库中,是按照double对A,B,C进行取值的,上面的调用方法没有问题,传递的值很正确,传到DLL中的1,2,4分别各占8个字节的内存.
但是如果将函数参数中的A,B,C变量换成常量就不行了,如下代码:
并且,这两句的效果也不相同,前者每个数占4个字节的内存,而后者却是每个数占12个字节.
请问我的动态链接库的代码该怎么写才能使这个函数可以正确接受这三种方式的调用时传到DLL中的值?
------解决方案--------------------
这是因为可变数量的参数,并不明了类型,Delphi对浮点立即数总是作为extended类型(80位扩展精度)传入的。
目前还没发现可以强制作为double参数的方法。
解决的方法:
1. 使用double类型变量作为参数,不要使用立即数;
2. 对C++函数稍加修改,适应Delphi的OpenArray方式的可变参数:
extern "C" __declspec(dllexport) void __cdecl AddVariables(char *, double *, int);
Delphi中的声明:
procedure AddVariables(VarList: PChar; Data: array of double); cdecl; external 'xxx.dll';
调用:
AddVariables('A,B,C', [a, 2, 3.0]);
传变量、整型立即数、浮点立即数,包括计算表达式都可以。
我用VC++2005写了一个动态链接库,导出了如下函数:
- C/C++ code
void SetVarialbels(char * VarList,...){ string VarNameList=string(VarList); string VarName; double VarValue=0.0; va_list arg_ptr; va_start(arg_ptr,VarList); do { VarName = GetVarName(VarNameList); if(VarName.length()>0) { VarValue = va_arg(arg_ptr,double); map<string,double>::iterator p; p=vars.find(VarName); if(p!=vars.end()) p->second = VarValue; else vars.insert(pair<const string,const double>(VarName,VarValue)); } } while(VarName.length()>0); va_end(arg_ptr); }
现在使用Delphi调用这个导出函数,在Delphi中声明如下:
procedure SetVariables(VarList:pChar);stdcall;varargs;external 'MyDll.dll';
调用时可以这样调用:
- Delphi(Pascal) code
var A,B,C:double; begin A:=1; B:=2; C:=4; SetVariables('A,B,C',A,B,C); end;
在动态链接库中,是按照double对A,B,C进行取值的,上面的调用方法没有问题,传递的值很正确,传到DLL中的1,2,4分别各占8个字节的内存.
但是如果将函数参数中的A,B,C变量换成常量就不行了,如下代码:
- Delphi(Pascal) code
SetVariables('A,B,C',1,2,4); //或者: SetVariables('A,B,C',1.0,2.0,4.0);
并且,这两句的效果也不相同,前者每个数占4个字节的内存,而后者却是每个数占12个字节.
请问我的动态链接库的代码该怎么写才能使这个函数可以正确接受这三种方式的调用时传到DLL中的值?
------解决方案--------------------
这是因为可变数量的参数,并不明了类型,Delphi对浮点立即数总是作为extended类型(80位扩展精度)传入的。
目前还没发现可以强制作为double参数的方法。
解决的方法:
1. 使用double类型变量作为参数,不要使用立即数;
2. 对C++函数稍加修改,适应Delphi的OpenArray方式的可变参数:
extern "C" __declspec(dllexport) void __cdecl AddVariables(char *, double *, int);
Delphi中的声明:
procedure AddVariables(VarList: PChar; Data: array of double); cdecl; external 'xxx.dll';
调用:
AddVariables('A,B,C', [a, 2, 3.0]);
传变量、整型立即数、浮点立即数,包括计算表达式都可以。