Как исправить недопустимые символы, которые отображаются в MessageBox в C ++ DLL при вызове из приложения Delphi? - PullRequest
0 голосов
/ 20 января 2019

Я использовал Code :: Blocks IDE для DLL и Delphi 10.3 Rio для Delphi.

Вот мои C ++ DLL коды (файл CPP):

#include "main.h"
#include "string"
#include "wchar2string.h"
using namespace std;
// a sample exported function
void DLL_EXPORT SomeFunction(wchar_t* sometext)
{
    string str = wchar2string(sometext);
    const char* cch = str.c_str();
    MessageBox(0, cch, "DLL Message", MB_OK | MB_ICONINFORMATION);
}

extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD     fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            // attach to process
            // return FALSE to fail DLL load
            break;

        case DLL_PROCESS_DETACH:
            // detach from process
            break;

        case DLL_THREAD_ATTACH:
            // attach to thread
            break;

        case DLL_THREAD_DETACH:
            // detach from thread
            break;
    }
    return TRUE; // succesful
}

Вот мой .H файл:

#ifndef __MAIN_H__
#define __MAIN_H__

#include <windows.h>

/*  To use this exported function of dll, include this header
 *  in your project.
 */

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif


#ifdef __cplusplus
extern "C"
{
#endif

void DLL_EXPORT SomeFunction(wchar_t* sometext);

#ifdef __cplusplus
}
#endif

#endif // __MAIN_H__

А вот мои коды Delphi:

const
  DLL = 'deneme dll.dll';

procedure MyProcedure(sometext: PWideChar); external DLL name 'SomeFunction';

procedure TForm1.Button1Click(Sender: TObject);
var
  MyString: String;
begin
  MyString := Edit1.Text;
  MyProcedure(PWideChar(MyString));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  SetErrorMode(0);
end;

end.

По данным этого сайта PWideChar является Delphi эквивалентом wchar_t * в C ++: http://rvelthuis.de/articles/articles-dlls.html

Итак, когда я нажал на Button1; Я получил это сообщение: enter image description here

И если DLL не найдена, приложение Delphi выдает следующее (сообщение «Приложение перестало работать»): enter image description here

Итак, SetErrorMode (0); не работает.

Что я имею в виду, я ничего не знаю о программировании DLL, и ни на одном веб-сайте нет никаких указаний по этому поводу.

Итак, что мне делать, чтобы это работало правильно?

1 Ответ

0 голосов
/ 21 января 2019

На стороне C ++ преобразование wchar_t* в std::string не требуется.Просто используйте вместо этого Unicode-версию MessageBox(), например:

void DLL_EXPORT SomeFunction(wchar_t* sometext)
{
    MessageBoxW(0, sometext, L"DLL Message", MB_OK | MB_ICONINFORMATION);
}

Однако основная причина вашей проблемы - несоответствие соглашения о вызовах.На стороне Delphi соглашение о вызовах по умолчанию - register, что очень отличается от значения по умолчанию __cdecl, используемого в C и C ++.Объявление Delphi функции DLL должно указывать правильное соглашение о вызовах, например:

procedure MyProcedure(sometext: PWideChar); cdecl; external DLL name 'SomeFunction';

procedure TForm1.Button1Click(Sender: TObject);
var
  MyString: UnicodeString;
begin
  MyString := Edit1.Text;
  MyProcedure(PWideChar(MyString));
end;
...