0

Embarcadero C ++ Builder XE3でDLLを作成し、同じ環境のテストプロジェクトで使用しようとしています。

コードで良い結果が得られないチュートリアルの例を取り上げます(!):http ://docwiki.embarcadero.com/RADStudio/XE3/en/Tutorial:_Using_Dynamic_Linked_Libraries_in_C%2B%2BBuilder_Applications

これが私のDLLの内容です:

BaseAuth.hファイル:

#ifndef   BaseAuthH
#define   BaseAuthH

#include <System.hpp>
class TBaseAuth
{
public:
    virtual void TestMessage() = 0;
};
#endif // BaseAuthH

Auth.hファイル:

//---------------------------------------------------------------------------
#ifndef AuthH
#define AuthH
//---------------------------------------------------------------------------
#include "BaseAuth.h"
class TAuth : public TBaseAuth
{
public:
    TAuth();
    ~TAuth();   
    void TestMessage();
};
#endif

Auth.cppファイル:

//---------------------------------------------------------------------------
#pragma hdrstop
#include "Auth.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
TAuth::TAuth()
{
}
TAuth::~TAuth()
{
}
void TAuth::TestMessage()
{
    MessageBox(0, "Test message", "Test", MB_OK);
}

およびFile1.cpp:

#pragma hdrstop
#pragma argsused

#include "Auth.h"
extern "C" __declspec(dllexport) void* __stdcall GetClassInstance()
{
    return static_cast<void*>(new TAuth());
}
extern "C" int _libmain(unsigned long reason)
{
    return 1;
}    

今テストアプリケーションで私は持っています:

  • 同じBaseAuth.hファイル

  • ボタン付きのフォーム:

Test_DLLAuthOrga.h:

#ifndef Test_DLLAuthOrgaH
#define Test_DLLAuthOrgaH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
#include "BaseAuth.h"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // Composants gérés par l'EDI
    TButton *Button2;
    void __fastcall Button2Click(TObject *Sender);
private:    // Déclarations utilisateur
    TBaseAuth *mpAuth;
public:     // Déclarations utilisateur
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Test_DLLAuthOrga.cpp:

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Test_DLLAuthOrga.h"
#include "BaseAuth.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
const wchar_t* library = L"DLLAuthOrga.dll";
extern "C" __declspec(dllimport) void* __stdcall GetClassInstance();
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
    HINSTANCE load;
    try
    { load = LoadLibrary(library); }
    catch(Exception &e)
    { ShowMessage(e.Message); }
    if (load)
    {
        ShowMessage("Library Loaded!");
        void *myFunc;
        myFunc = (void *)GetProcAddress(load, "GetClassInstance");
        mpAuth = (AuthParent*)myFunc;
    }
    else { ShowMessage("Library not loaded!"); }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    if (mpAuth == NULL) return;
    try { pRes = mpAuth->TestMessage(); }
    catch(Exception &e) { ShowMessage(e.Message); return; }
}

結果は次のとおりです。

ポインタmpAuthにはアドレスがあります。

しかし、そのメソッドにはアドレスがなく、「void TestMessage()」などの単純なメソッドを呼び出すと、アクセス違反が発生します。

=>最初は文字列の互換性の問題のようでした(ただし、「C++BuilderXE3」と「C++BuilderXE3」の間では同じ文字列形式が使用されると思いますか?!):UnicodeDelphiでDLLを呼び出すときにエラーが発生しました

=>同様の問題が見つかりましたが、C ++DLLをDelphiに変換し、C ++DLLをC++に変換しませんでした...:DelphiアプリでC++DLLを呼び出します

=>「HINSTANCEload;」の代わりに「HMODULE」を使用してみました。:同じ結果。

=>使用して成功せずに試しました

mpAuth = static_cast<AuthParent*>(myFunc);

それ以外の :

mpAuth = (AuthParent*)myFunc;

=>また、「__stdcall」を「__cdecl」または「」(削除)に置き換えてみました。librayはロードされますが、GetProcAdressはNULLを返します。

=> DLLのメソッド「TestMessage()」を呼び出そうとして、何が間違っているのでしょうか。

4

1 に答える 1