将VB6布尔变量传递给C ++ DLL中的stdcall函数

时间:2014-11-09 21:52:09

标签: c++ com vb6 stdcall

我正在寻找将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。 我知道那不太好,但我没有看到任何其他方式。

我的代码中是否有人发现了错误?

2 个答案:

答案 0 :(得分:2)

BOOLint的类型定义。

它在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)。否则,您将受项目文件和其他头文件中指定的选项的支配。即使您对编译器使用的默认值感到满意,您的公共头文件也应该是显式的,因为最终有人会尝试在同一个程序中使用两个库,而另一个库可能要求更改编译选项。