0

我正在寻找将 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 Boolean、C++ BOOL 和 C++ bool。我知道这不太好,但我看不到任何其他方式。

有人发现我的代码有问题吗?

4

2 回答 2

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 位整数),而不是 Boolean。0 表示假,否则(通常为 1)为真。

于 2014-11-09T22:05:31.257 回答
2

默认情况下,VB6 使用 StdCall 调用约定(如果您创建一个类型库,其中包含module描述您的导入的部分,而不是使用 ,则支持 cdecl 约定Declare Function)。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)。否则,您将受到项目文件和其他头文件中指定的选项的支配。即使您对编译器使用的默认值感到满意,您的公共头文件也应该是明确的,因为最终有人会尝试在同一个程序中使用两个库,而另一个库可能会要求更改编译选项。

于 2014-11-10T02:21:24.880 回答