我正在寻找将VB6布尔变量传递给函数(用C ++编写,stdcall)最安全的方法。
C ++函数将使用此VB6变量设置结构的“bool”变量。
我试过在C ++中声明这样:
extern "C" __declspec(dllexport) int SetParameter( BOOL bErrorView)
{
DLL_sSettings nSet;
nSet.bErrorView =(bErrorView != FALSE);
int ret = stSetParameter(sizeof(DLL_sSettings), nSet);
return (ret);
}
stSetParameter声明为
extern "C" int ST_COMDLL_API stSetParameter(int DataLen, DLL_sSettings Settings);
DLL_sSetting声明为
typedef struct
{
bool bErrorView; // true: Show
// false: Don't show
(...)
} DLL_sSettings;
但是,我无法让它发挥作用。
我使用
在VB6中调用它Private Declare Function SetParameter Lib "MyDLL.dll" Alias "_SetParameter@4" (ByVal bErrorView As Boolean) As Long
但它没有按预期工作,我想某处VB6布尔值丢失或被错误转换。
我目前正在使用VB6布尔值,C ++ BOOL和C ++ bool。 我知道那不太好,但我没有看到任何其他方式。
我的代码中是否有人发现了错误?
答案 0 :(得分:2)
BOOL
是int
的类型定义。
它在windef.h中声明如下:
typedef int BOOL;
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
bool
是C ++类型,如果用extern "C"
声明函数,则不能在函数原型中使用。
因此VB应该将BOOL视为Long(32位整数),而不是Bolean。 0表示错误,否则(通常为1)是真的。
答案 1 :(得分:2)
默认情况下,VB6使用StdCall调用约定(如果您创建一个描述导入的module
部分的类型库,而不是使用Declare Function
),则支持cdecl约定。 C ++支持大量的调用约定:stdcall,fastcall,cdecl,thiscall。
重要的是要注意,在另一个库中使用stdcall调用函数不足以将函数更改为stdcall。您可以使用命令行切换到编译器,但最强大的是在源代码中包含__stdcall
关键字。它将应用于函数的名称,如下所示:
int __stdcall functionname(int args);
由于您还希望导出VB6的这些函数来查找它们,因此您希望extern "C"
减少名称重写,并__declspec(dllexport)
将它们放在导出表中。
使用宏一次完成上述所有操作非常常见。看起来你要包装的库使用ST_COMDLL_API
执行此操作。在库内,它将扩展为__declspec(dllexport) __stdcall
。对于消费者,它将使用dllimport
代替。
每当您定义要在不同编译器(甚至不同语言)中使用的API时,最好非常明确地调用约定和结构打包(#pragma pack
)。否则,您将受项目文件和其他头文件中指定的选项的支配。即使您对编译器使用的默认值感到满意,您的公共头文件也应该是显式的,因为最终有人会尝试在同一个程序中使用两个库,而另一个库可能要求更改编译选项。