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

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)。そうしないと、プロジェクト ファイルやその他のヘッダー ファイルで指定されたオプションに翻弄されてしまいます。コンパイラが使用するデフォルトに満足している場合でも、公開ヘッダーは明示的である必要があります。これは、最終的に誰かが同じプログラムで 2 つのライブラリを使用しようとし、他のライブラリがコンパイル オプションの変更を要求する可能性があるためです。

于 2014-11-10T02:21:24.880 に答える