3

我正在尝试在 C++ 中创建一个 DLL 并导出一个函数。

这是我的 C++ 代码:

#include <Windows.h>

void DLLMain(){

}

__declspec(dllexport) void xMain(){
MessageBox(NULL,L"Test",L"Test",NULL);
}

这是我的德尔福代码:

program prjTestDllMain;

Uses
  Windows;

Var
  xMainPrc:procedure;stdcall;
  handle : THandle;
begin
    handle := LoadLibrary('xdll.dll');
    if handle <> 0 then
    begin
        MessageBox(0,'DLL Loaded', 0, 0);
        @xMainPrc := GetProcAddress(handle, 'xMain');
        if @xMainPrc <> nil then
            MessageBox(0,'Function Loaded', 0, 0)
        else
          MessageBox(0,'Function Not Loaded', 0, 0);
        MessageBox(0,'Process End', 0, 0);
        FreeLibrary(handle);
    end else
      MessageBox(0,'DLL Not Loaded', 0, 0);
end.

我得到一个“DLL Loaded”的消息框就好了。但之后我得到“未加载功能”。我在这里做错了什么?

4

2 回答 2

6

您可以将它导出为 C 函数 ( __cdecl),以便它在导出表上具有一个好听的名称。

名称装饰约定:下划线字符 (_) 作为名称的前缀,导出使用 C 链接的 __cdecl 函数时除外。

所以基本上,您的函数将xMain在导出表中具有名称。

extern "C" __declspec(dllexport) void xMain()

在 Delphi 部分,您只需指定cdecl并正常调用它:

var
  xMainPrc: procedure; cdecl;

例如:

if @xMainPrc <> nil then
begin
  MessageBox(0,'Function Loaded', 0, 0);
  xMainPrc;
end;
于 2012-11-26T04:47:36.127 回答
2

使用调用约定导出函数__stcall(特别是因为您尝试使用stdcallDelphi 中的调用约定导入它),并用于extern "C"删除任何导出的名称装饰:

MyDll.h

#ifndef MyDLLH
#define MyDLLH

#ifdef __BUILDING_DLL
#define MYDLLEXPORT __declspec(dllexport)
#else
#define MYDLLEXPORT __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif

MYDLLEXPORT void __stdcall xMain();

#ifdef __cplusplus
}
#endif

#endif

.

MyDll.cpp

#define __BUILDING_DLL
#include "MyDll.h"

#include <Windows.h>

void DLLMain()
{
}

void __stdcall xMain()
{
    MessageBox(NULL, L"Test", L"Test", NULL);
}

.

prjTestDllMain.dpr

program prjTestDllMain;

uses
  Windows;

var
  xMainPrc: procedure; stdcall;
  handle : THandle;
begin
  handle := LoadLibrary('xdll.dll');
  if handle <> 0 then
  begin
    MessageBox(0,'DLL Loaded', 0, 0);
    @xMainPrc := GetProcAddress(handle, 'xMain');
    if @xMainPrc <> nil then
    begin
      MessageBox(0,'Function Loaded', 0, 0)
      xMainPrc();
    end else
      MessageBox(0,'Function Not Loaded', 0, 0);
    MessageBox(0,'Process End', 0, 0);
    FreeLibrary(handle);
  end else
    MessageBox(0,'DLL Not Loaded', 0, 0);
end.

或者:

prjTestDllMain.dpr

program prjTestDllMain;

uses
  Windows;

procedure xMain; stdcall; extern 'MyDll.dll';

begin
  MessageBox(0,'DLL Loaded', 0, 0);
  xMain();
  MessageBox(0,'Process End', 0, 0);
end.
于 2012-11-26T22:07:32.497 回答