如何修复从Delphi应用程序调用它时在C ++ DLL中的MessageBox中显示的无效字符?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何修复从Delphi应用程序调用它时在C ++ DLL中的MessageBox中显示的无效字符?相关的知识,希望对你有一定的参考价值。

我使用Code :: Blocks IDE for DLL和Delphi 10.3 Rio for Delphi app。

这是我的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相当于C ++中的wchar_t *:http://rvelthuis.de/articles/articles-dlls.html

所以,当我点击Button1时;我收到了这条消息:enter image description here

如果找不到DLL,Delphi app会抛出这个('Application Stopped Working'消息):enter image description here

所以,SetErrorMode(0);不管用。

我的意思是,我对DLL编程一无所知,并且在任何网站上都没有任何关于它的指南。

那么,我该怎么做才能使其正常工作?

答案

在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,它与C和C ++中使用的__cdecl的默认值非常不同。 DLL函数的Delphi声明需要指定正确的调用约定,例如:

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;

以上是关于如何修复从Delphi应用程序调用它时在C ++ DLL中的MessageBox中显示的无效字符?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Delphi 调用 _putenv?

尝试从 VS2013 C# 程序调用 DELPHI XE2 DLL 时出错

如何在Delphi中使用用C#创建的DLL

如何通过 Visual Studio 修复功能应用发布中的错误

从Delphi调用C ++ DLL时发生访问冲突

c ++指针将结构新数组指向delphi到DLL函数